序章
歡迎使用 Google 的 Python 線上教學課程。這以內部提供的 Python 入門課程為基礎。如設定網頁所述,本文的內容涵蓋 Python 3。
如要尋找隨附 MOOC 課程,請試試 Udacity 和 Coursera 的課程 (程式設計簡介 [新手] 或 Python 簡介)。最後,如果您的目標是在「不」觀看影片的情況下,自主學習線上學習方式,可以試試這篇文章結尾列出的操作,每種功能學習內容以及 Python 互動式翻譯工具都是供您練習使用。我們提及的「口譯」是什麼?我們將在下一節中說明。
語言簡介
Python 是一種動態解譯 (位元碼編譯) 語言。原始碼中沒有任何變數、參數、函式或方法的類型宣告。如此一來,程式碼會變得簡短且有彈性,您也會失去原始碼的編譯時間類型檢查功能。Python 會在執行階段追蹤所有值的類型,並標記在執行過程中不合理的程式碼。
查看 Python 程式碼運作方式的絕佳方法,就是執行 Python 解譯器,然後直接輸入程式碼。如果您有任何疑問,例如「如果將 int
新增至 list
,會發生什麼事?」,只要在 Python 解譯器中輸入該問題,就能快速瞭解情況,也或許是最佳方式。(詳情請參閱下方說明!)
$ python3 ## Run the Python interpreter Python 3.X.X (XXX, XXX XX XXXX, XX:XX:XX) [XXX] on XXX Type "help", "copyright", "credits" or "license" for more information. >>> a = 6 ## set a variable in this interpreter session >>> a ## entering an expression prints its value 6 >>> a + 2 8 >>> a = 'hi' ## 'a' can hold a string just as well >>> a 'hi' >>> len(a) ## call the len() function on a string 2 >>> a + len(a) ## try something that doesn't work Traceback (most recent call last): File "", line 1, in TypeError: can only concatenate str (not "int") to str >>> a + str(len(a)) ## probably what you really wanted 'hi2' >>> foo ## try something else that doesn't work Traceback (most recent call last): File " ", line 1, in NameError: name 'foo' is not defined >>> ^D ## type CTRL-d to exit (CTRL-z in Windows/DOS terminal)
在您輸入 Python 之後以及 >>> 提示前,這兩行會輸出 Python 文字,讓您瞭解自己使用的 Python 版本以及建構位置。只要第一個輸出的內容是「Python 3」,這些範例應該就能用。
如上所述,透過變數和運算子輕鬆進行實驗。此外,如果程式碼嘗試讀取尚未指派值的變數,解譯器在 Python 剖析中會擲回或「raises」。和 C++ 和 Java 一樣,Python 會區分大小寫,因此「a」和「A」是不同的變數。行的結尾會標示陳述式的結尾,因此與 C++ 和 Java 不同,Python 不需要在每個陳述式的結尾加上分號。註解會以「#」開頭,延伸至行結尾。
Python 原始碼
Python 來源檔案使用「.py」副檔名,稱為「modules」。使用 Python 模組 hello.py
執行時,最簡單的方法是使用殼層指令「Python hello.py Alice」,呼叫 Python 解譯器執行 hello.py
中的程式碼,並將指令列引數「Alice」傳遞給該程式碼。請參閱官方說明文件頁面,瞭解透過指令列執行 Python 時可用的所有選項。
以下是非常簡單的 hello.py
程式 (請注意,程式碼區塊是以縮排而非大括號分隔,本文稍後將進一步說明!):
#!/usr/bin/python3 # import modules used here -- sys is a very standard one import sys # Gather our code in a main() function def main(): print('Hello there', sys.argv[1]) # Command line args are in sys.argv[1], sys.argv[2] ... # sys.argv[0] is the script name itself and can be ignored # Standard boilerplate to call the main() function to begin # the program. if __name__ == '__main__': main()
從指令列執行這個程式如下所示:
$ python3 hello.py Guido Hello there Guido $ ./hello.py Alice ## without needing 'python3' first (Unix) Hello there Alice
匯入項目、指令列引數和 len()
Python 檔案 (或模組) 中最外層的陳述式只需進行一次性設定,也就是在第一次匯入模組時由上往下執行,並設定其變數和函式。Python 模組可直接執行 (如 python3 hello.py Bob
所示),或是可由其他模組匯入及使用。直接執行 Python 檔案時,特殊變數「__name__」會設為 "__main__"。因此,直接在模組執行時呼叫上方的樣板 if __name__ ==...
呼叫 main() 函式是很常見的情況,但如果模組是由其他模組匯入,是很常見的情況。
在標準 Python 程式中,sys.argv
清單包含標準的指令列引數,其中 sys.argv[0] 是程式本身,sys.argv[1] 第一個引數,依此類推。如果您瞭解 argc
或引數數量,可以直接使用 len(sys.argv)
從 Python 要求這個值,就像在要求字串長度時在上述互動式直譯器程式碼中一樣。一般來說,len()
會指出字串的長度、清單和元組中的元素數量 (另一個類似陣列的資料結構),以及字典中的鍵/值組合數量。
使用者定義的函式
Python 中的函式定義如下:
# Defines a "repeat" function that takes 2 arguments. def repeat(s, exclaim): """ Returns the string 's' repeated 3 times. If exclaim is true, add exclamation marks. """ result = s + s + s # can also use "s * 3" which is faster (Why?) if exclaim: result = result + '!!!' return result
請注意,構成函式或 if-陳述式的行數如何按縮排層級分組。我們還提供了 2 種不同的字串方式,您可以使用 + 運算子,因為這是 Python 的「重複」運算子,所以 * 也能正常運作,因為 '-' * 10
提供了 '----------'
,讓建立螢幕「線」的便捷方式。在程式碼註解中,我們提示 * 運作速度比 + 快,原因為 * 計算結果物件的大小一次,而 + 則在每次呼叫 + 時進行計算。+ 和 * 皆稱為「超載」,因為兩者代表數字與字串 (以及其他資料類型) 的意義不同。
def
關鍵字會使用括號內的參數定義函式,程式碼已縮排。函式的第一行可以是說明函式的說明文件字串 (「docstring」)。docstring 可以是單行,也可以是多行說明,如上例所示。(當然是「三引號」,這是 Python 特有的功能!)函式中定義的變數位於該函式的本機中,因此上述函式中的「result」會與另一個函式中的「result」變數分開。return
陳述式可接受引數,在此情況下,系統會將值傳回給呼叫端。
以下程式碼會呼叫上述 repeat() 函式,並輸出傳回的內容:
def main(): print(repeat('Yay', False)) ## YayYayYay print(repeat('Woo Hoo', True)) ## Woo HooWoo HooWoo Hoo!!!
在執行階段,函式必須先由執行「def」執行作業定義,然後呼叫函式。一般而言,使用其在上呼叫的函式將 main() 函式定義在檔案底部。
縮排
一個不尋常的 Python 功能是一段程式碼的空白字元縮排會影響其意義。像是組成函式的陳述式邏輯區塊都應具有相同的縮排,請從父項函式的縮排、「if」或其他條件中設定。如果群組中其中某一行的縮排不同,系統會將其標記為語法錯誤。
Python 一開始使用空白字元可能會讓人覺得有點奇怪,但這很有邏輯,我發現我很快就習慣。避免使用 TAB,因為這類策略會大幅簡化縮排架構 (請注意,TAB 在不同平台上可能代表不同的意思)。將編輯器設為插入空格,而不是 Python 程式碼的 TAB。
常見的問題是「我應該將多少空格縮排?」根據官方 Python 樣式指南 (PEP 8),您應使用 4 個空格縮排。(趣味小知識:Google 內部的樣式規範將以 2 個空格表示縮排!)
在執行階段檢查程式碼
Python 的編譯時間幾乎不會進行檢查,延遲幾乎所有類型、名稱等檢查,直到該行執行為止。假設上述 main() 呼叫 repeat(),如下所示:
def main(): if name == 'Guido': print(repeeeet(name) + '!!!') else: print(repeat(name))
if-statement 內含顯而易見的錯誤,也就是 repeat() 函式意外輸入為 repeeeet()。在 Python 中,這個有趣的事...只要執行階段名稱不是「Guido」,這個程式碼就可以正常編譯並執行。只有在執行作業實際嘗試執行 repeeeet() 時,才會發現並沒有這類函式,並引發錯誤。此外,這個程式碼片段還有第二個錯誤。名稱就和「Guido」比較之前並未指派值若您嘗試評估未指派的變數,Python 會發出「NameError」。這些範例顯示了當您第一次執行 Python 程式時,您看到的前幾個錯誤會是簡單的錯字或這類變數尚未初始化。這有缺點,也就是 Java 這類較詳細類型系統的語言有優勢...它們可以在編譯期間找出這類錯誤 (不過您當然需要維護所有類型資訊,這是缺點)。
Python 3 推出了類型提示。您可以透過類型提示指出函式中每個引數的類型,以及函式傳回的物件類型。例如,在註解函式 def is_positive(n: int) -> bool:
中,引數 n
為 int
,且回傳值為 bool
。我們稍後會進一步說明這些類型代表的意義。不過,類型提示完全可以自由選用。您會看到越來越多採用類型提示的程式碼,因為使用類型提示時,某些編輯器 (例如 cider-v 和 VS.code) 可以執行檢查,確認使用正確的引數類型呼叫函式。還可以在您編輯程式碼時提供及驗證引數。本教學課程不會涵蓋類型提示,但我們希望確保您能留意這些提示,或在野外觀看。
變數名稱
由於 Python 變數在原始碼中並沒有點名的類型,因此為變數加上有意義的名稱,提醒您注意實際情況。因此如果是單一名稱,請使用「names」;如果是名稱清單,請使用「names」;如果是元組清單,則請使用「 元組」。在許多基本 Python 錯誤中,都是因為忘記每個變數裡哪種類型的值,所以請善用變數名稱 (您擁有的所有變數) 來保持工作原理。
就實際的命名方式而言,有些語言偏好使用底線名稱來當做「多個字詞」的變數名稱,但其他語言則偏好使用底線。一般而言,Python 會偏好底線方法,但會在整合到已使用該樣式的現有 Python 程式碼時,引導開發人員延後使用駝峰式命名法。可讀性計數。詳情請參閱 PEP 8 的命名慣例一節。
就您猜到,「if」和「while」等關鍵字不能用做變數名稱,否則系統會發生語法錯誤。不過請注意,請勿使用內建函式做為變數名稱。例如,「str」、「list」和「print」看起來像是好名字,但其實是覆寫這些系統變數。內建不是關鍵字,因此,新的 Python 開發人員可能會意外使用這些項目。
進一步瞭解模組及其命名空間
假設您有一個包含「def foo()」的模組「binky.py」,該 foo 函式的完整名稱就是「binky.foo」。這樣一來,各種 Python 模組都可以任意命名函式和變數,而且變數名稱不會衝突 — module1.foo 與 module2.foo 不同。在 Python 詞彙中,我們會假設 binky、module1 和 module2 各有專屬的「namespaces」,所以您的猜測是變數名稱對物件的繫結。
舉例來說,我們有標準「sys」模組,這個模組包含一些標準系統功能,例如 argv 清單和 exit() 函式。透過「import sys」陳述式,您可以存取 sys 模組中的定義,並使用其完整名稱提供定義,例如 sys.exit()。(可以,'sys' 也有命名空間!)
import sys # Now can refer to sys.xxx facilities sys.exit(0)
另一個匯入表單看起來像這樣:「從 sys import argv, exit」。這樣一來,簡稱 argv 和 exit() 的簡稱;不過,建議您使用完整的名稱在原始表單中使用完整的名稱,因為這樣能更容易判斷函式或屬性的來源。
有許多模組和套件隨附標準 Python 解譯器,因此您不必額外進行操作即可使用。以上這些統稱為「Python 標準程式庫」。常用的模組/套件包括:
- sys — access to exit(), argv, stdin, stdout, ...
- re — 規則運算式
- os — 作業系統介面、檔案系統
您可以在 http://docs.python.org/library 找到所有標準程式庫模組和套件的說明文件。
線上說明、help()
和dir()
您可以透過多種方式取得 Python 相關說明。
- 以「Python」這個字詞開頭執行 Google 搜尋,例如「Python list」或「python string 小寫」。第一筆命中通常就是答案。因為某些原因,這項技巧在 Python 上的成效似乎比其他語言更好。
- Python 官方文件網站 docs.python.org 提供優質文件。儘管如此,我在 Google 上搜尋幾個字詞,可以更快找到所需資訊。
- 我們還提供了專為 Python 和/或程式設計新手設計的官方家教郵寄清單!
- 您可以在 StackOverflow 和 Quora 找到許多問題和解答。
- 使用 help() 和 dir() 函式 (請見下文)。
在 Python 解譯器中,help() 函式會提取各種模組、函式及方法的說明文件字串。這些文件字串與 Java 的 javadoc 類似。dir() 函式會指出物件的屬性為何。以下提供一些透過解譯器呼叫 help() 和 dir() 的方法:
help(len)
— 內建len()
函式的說明字串;請注意,它是「len」而不是「len()」,這是對函式的呼叫,我們不希望help(sys)
:sys
模組的說明字串 (必須先執行import sys
)dir(sys)
—dir()
與help()
類似,但只是簡單列出已定義的符號或「屬性」清單help(sys.exit)
:sys
模組中exit()
函式的說明字串help('xyz'.split)
:字串物件的split()
方法說明字串。您可以使用該物件本身或該物件的範例,及其屬性來呼叫help()
。舉例來說,呼叫help('xyz'.split)
與呼叫help(str.split)
相同。help(list)
:list
物件的說明字串dir(list)
:顯示list
物件屬性 (包括其方法)help(list.append)
:list
物件的append()
方法說明字串