Python 簡介

序章

歡迎使用 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: 中,引數 nint,且回傳值為 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 和/或程式設計新手設計的官方家教郵寄清單
  • 您可以在 StackOverflowQuora 找到許多問題和解答。
  • 使用 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() 方法說明字串