1. 引言

本參考手冊描述了 Python 程式語言。它並非用作教程。

雖然我力求精確,但除了語法和詞法分析之外,我選擇使用英語而非形式化規約來描述所有內容。這應該能讓普通讀者更容易理解該文件,但也會留下模糊不清的餘地。因此,假如你來自火星,並試圖僅根據這份文件來重新實現 Python,你可能需要靠猜測,而實際上你最終實現的可能會是相當不同的語言。另一方面,如果你正在使用 Python,並且想知道該語言某個特定方面的精確規則,你絕對可以在這裡找到它們。如果你想看到對該語言更形式化的定義,或許你可以自願貢獻你的時間——或者發明一臺克隆機 :-)。

在語言參考文件中加入過多的實現細節是危險的——實現可能會改變,而同一語言的其他實現方式也可能不同。另一方面,CPython 是目前廣泛使用的 Python 實現(儘管其他替代實現的支援度也在不斷增加),其特有的怪癖有時也值得一提,特別是當該實現施加了額外限制時。因此,你會在文中發現散佈著簡短的“實現說明”。

每個 Python 實現都附帶了許多內建模組和標準模組。這些模組的文件記錄在《Python 標準庫》中。當一些內建模組與語言定義有重要互動時,本文會提及它們。

1.1. 其他實現

儘管有一個 Python 實現迄今為止最為流行,但還有一些替代實現對於不同受眾具有特別的吸引力。

已知的實現包括:

CPython

這是 Python 的原始實現,也是維護最積極的實現,用 C 語言編寫。新的語言特性通常會最先在這裡出現。

Jython

用 Java 實現的 Python。此實現可作為 Java 應用程式的指令碼語言,或用於建立使用 Java 類庫的應用程式。它也常用於為 Java 庫建立測試。更多資訊可以在 Jython 網站上找到。

Python for .NET

該實現實際上使用了 CPython 實現,但它是一個託管的 .NET 應用程式,並提供了 .NET 庫的訪問。它由 Brian Lloyd 建立。更多資訊請參閱 Python for .NET 主頁

IronPython

另一個 Python for .NET 的實現。與 Python.NET 不同,這是一個完整的 Python 實現,可以生成 IL,並將 Python 程式碼直接編譯成 .NET 程式集。它由 Jython 的最初建立者 Jim Hugunin 建立。更多資訊請參閱 IronPython 網站

PyPy

一個完全用 Python 編寫的 Python 實現。它支援一些在其他實現中找不到的高階特性,如無棧(stackless)支援和即時(Just in Time)編譯器。該專案的目標之一是透過讓修改直譯器變得更容易(因為它是由 Python 編寫的)來鼓勵對語言本身的實驗。更多資訊可在 PyPy 專案主頁上獲得。

這些實現中的每一個都在某些方面與本手冊中記錄的語言有所不同,或者引入了標準 Python 文件未涵蓋的特定資訊。請參考特定實現的文件,以確定你需要了解的關於你所使用的具體實現的更多資訊。

1.2. 表示法

詞法分析和語法的描述使用一種混合了 EBNFPEG 的文法表示法。例如:

name:   letter (letter | digit | "_")*
letter: "a"..."z" | "A"..."Z"
digit:  "0"..."9"

在此示例中,第一行表示一個 name 是一個 letter,後跟零個或多個 letterdigit 和下劃線組成的序列。而一個 letter'a''z'AZ 之間的任意單個字元;一個 digit09 之間的任意單個字元。

每條規則都以一個名稱(用於標識正在定義的規則)開頭,後跟一個冒號 :。冒號右側的定義使用以下語法元素:

  • name: 名稱引用另一條規則。在可能的情況下,它會連結到該規則的定義。

    • TOKEN: 大寫名稱引用一個詞法單元(token)。在文法定義中,詞法單元與規則等同。

  • "text", 'text': 單引號或雙引號中的文字必須逐字匹配(不包括引號)。引號的型別根據 text 的含義選擇:

    • 'if': 單引號中的名稱表示一個關鍵字

    • "case": 雙引號中的名稱表示一個軟關鍵字

    • '@': 單引號中的非字母符號表示一個 OP 詞法單元,即一個定界符運算子

  • e1 e2: 僅由空格分隔的項表示一個序列。這裡,e1 必須後跟 e2

  • e1 | e2: 豎線用於分隔備選項。它表示 PEG 的“有序選擇”:如果 e1 匹配,則不再考慮 e2。在傳統的 PEG 文法中,這通常寫作斜槓 /,而不是豎線。更多背景和細節請參見 PEP 617

  • e*: 星號表示前一項重複零次或多次。

  • e+: 同樣,加號表示重複一次或多次。

  • [e]: 方括號內的短語表示出現零次或一次。換句話說,括號內的短語是可選的。

  • e?: 問號與方括號的含義完全相同:前一項是可選的。

  • (e): 圓括號用於分組。

以下表示法僅用於詞法定義

  • "a"..."z": 由三個點分隔的兩個字面字元表示在給定的 ASCII 字元範圍(含兩端)內任選一個字元。

  • <...>: 尖括號內的短語給出了對匹配符號的非正式描述(例如,<any ASCII character except "\">),或在附近文字中定義的縮寫(例如,<Lu>)。

一些定義還使用*先行斷言*(lookaheads),它表示一個元素必須(或必須不)在給定位置匹配,但不會消耗任何輸入:

  • &e: 肯定先行斷言(即,要求 e 必須匹配)

  • !e: 否定先行斷言(即,要求 e *不*匹配)

一元運算子(*+?)的繫結優先順序最高;豎線(|)的繫結優先順序最低。

空白字元僅用於分隔詞法單元。

規則通常包含在一行內,但過長的規則可能會換行:

literal: stringliteral | bytesliteral
         | integer | floatnumber | imagnumber

或者,規則也可以格式化為第一行在冒號處結束,每個備選項以豎線開頭並另起一行。例如:

literal:
   | stringliteral
   | bytesliteral
   | integer
   | floatnumber
   | imagnumber

這並*不*意味著存在一個空的第一個備選項。

1.2.1. 詞法和句法定義

*詞法*分析和*句法*分析之間存在一些差異:詞法分析器處理輸入源的單個字元,而*解析器*(句法分析器)則處理詞法分析生成的詞法單元流。然而,在某些情況下,這兩個階段之間的確切界限是 CPython 的實現細節。

兩者之間的實際區別在於,在*詞法*定義中,所有空白字元都是有意義的。詞法分析器會丟棄所有未被轉換為 token.INDENTNEWLINE 等詞法單元的空白字元。然後,*句法*定義使用這些詞法單元,而不是源字元。

本文件對兩種風格的定義使用相同的 BNF 文法。下一章(詞法分析)中所有 BNF 的用法都是詞法定義;後續章節中的用法則是句法定義。