Python 的程式碼執行涉及詞彙分析、語法分析、編譯和執行等多個階段。詞彙分析將程式碼分解成 token,例如關鍵字、運算子、識別符號等。接著,語法分析器將這些 token 組合成抽象語法樹(AST),表示程式碼的結構。Python 的解析過程包含兩個步驟:首先建立具體語法樹(CST),然後再由 CST 建立 AST。CST 保留了程式碼的完整語法細節,而 AST 則更關注程式碼的邏輯結構,方便後續的編譯和執行。Python 3.9 開始採用 PEG 語法,相比之前的 LL(1) 語法,PEG 更具彈性且功能更強大,能更精確地描述 Python 的語法規則。

重建語法檔案

為了更新Python的語法規則,需要重新編譯語法檔案。這個過程可以透過執行特定的指令來完成。在 macOS 和 Linux 系統上,可以使用 make regen-pegen 指令:

$ make regen-pegen

在 Windows 系統上,需要在 PCBuild 目錄下執行 build.bat 指令碼,並加上 --regen 引數:

> build.bat --regen

重新編譯語法檔案後,會產生一個新的 parse.c 檔案,這代表著新的語法規則已經被更新到 Python 的編譯器中。

測試新的語法規則

重新編譯 Python 後,可以執行新的二進位制檔案並啟動 REPL(Read-Eval-Print Loop)環境。然後,可以測試新的語法規則,例如定義一個使用 proceed 關鍵字的函式:

>>> def example():
...     proceed

如果沒有出現錯誤訊息,代表新的語法規則已經成功更新。

標記(Token)與語法

除了語法規則外,Python 還有另一份檔案 Grammar/Tokens,其中定義了所有可能出現在程式碼中的標記(Token)。每個標記都有一個唯一的名稱和識別碼,例如左括號被稱為 LPAR,而分號被稱為 SEMI。這些標記在語法分析的過程中扮演著重要的角色。

以下是一些範例標記:

  • LPAR: 左括號 (
  • RPAR: 右括號 )
  • LSQB: 左方括號 [
  • RSQB: 右方括號 ]
  • COLON: 冒號 :
  • COMMA: 逗號 ,

這些標記將在後續章節中被更詳細地討論。

瞭解Python語言的基礎:語法和詞彙

Python是一種高階語言,其語法和詞彙是構建程式的基礎。要了解Python語言,首先需要熟悉其語法規則和詞彙定義。

語法規則

Python的語法規則包括變數定義、控制結構、函式定義等。例如,變數定義使用=運算子,控制結構使用ifforwhile等關鍵字,函式定義使用def關鍵字。

詞彙定義

Python的詞彙定義包括識別符號、關鍵字、運算子等。識別符號是用來命名變數、函式和類別的字串,關鍵字是Python語言中預先定義的特殊字串,運算子是用來進行運算的特殊字元。

使用tokenize模組分析Python程式碼

Python的tokenize模組可以用來分析Python程式碼,將程式碼分解成個別的詞彙。這個模組可以幫助我們瞭解Python程式碼的結構和語法規則。

執行tokenize模組

要執行tokenize模組,需要建立一個Python指令碼,並將其作為引數傳遞給tokenize模組。例如,可以建立一個名為test_tokens.py的指令碼,內容如下:

# Demo application

def my_function():
    proceed

然後,執行以下命令:

$./python -m tokenize -e test_tokens.py

這將輸出程式碼的詞彙分析結果,包括詞彙的型別和位置。

詞彙分析結果

詞彙分析結果包括以下幾個部分:

  • ENCODING: 編碼宣告
  • COMMENT:註解
  • NAME: 識別符號
  • LPAR: 左括號
  • RPAR: 右括號
  • COLON: 冒號
  • NEWLINE: 新行
  • INDENT:縮排
  • DEDENT: 函式宣告結束
  • ENDMARKER: 檔案結束

每個詞彙都有一個對應的值,例如ENCODING的值是'utf-8'

使用debug模式執行Python程式碼

Python的debug模式可以幫助我們瞭解程式碼的執行過程和語法規則。要啟用debug模式,需要在執行Python程式碼時新增-d引數。

執行debug模式

例如,可以執行以下命令:

$./python -d test_tokens.py

這將輸出程式碼的執行過程和語法規則分析結果。

執行過程分析結果

執行過程分析結果包括以下幾個部分:

  • file[0-0]: 檔案分析
  • statements[0-0]: 陳述式分析
  • _loop1_11[0-0]: 迴圈分析

每個部分都有一個對應的值,例如file[0-0]的值是statements? $

透過使用tokenize模組和debug模式,可以更好地瞭解Python語言的基礎:語法和詞彙。這有助於我們更好地學習和使用Python語言。

Python語言的基礎知識

Python是一種高階的、解釋性的程式語言,它的語法簡潔易懂,適合初學者學習。Python的語法是由一組規則組成的,這些規則定義瞭如何寫出正確的Python程式碼。

Python的語法結構

Python的語法結構包括變數、資料型別、運算子、控制結構、函式、模組等。變數是用來儲存資料的容器,資料型別決定了變數可以儲存的資料型別。運算子用於對變數進行運算,控制結構用於控制程式碼的流程,函式是可重用的程式碼塊,模組是用於組織和重用程式碼的單元。

Python的資料型別

Python有多種資料型別,包括整數、浮點數、字串、列表、元組、字典等。整數是整數型別的資料,浮點數是小數型別的資料,字串是字元型別的資料,列表是一種可變的有序集合,元組是一種不可變的有序集合,字典是一種無序的鍵值對集合。

Python的控制結構

Python的控制結構包括if陳述式、for陳述式、while陳述式等。如果陳述式用於根據條件執行不同的程式碼塊,for陳述式用於遍歷序列中的元素,while陳述式用於重複執行一段程式碼。

Python的函式

Python的函式是可重用的程式碼塊,可以接受引數和傳回值。函式可以用於封裝程式碼,減少程式碼冗餘,提高程式碼的可讀性和可維護性。

Python的模組

Python的模組是用於組織和重用程式碼的單元。模組可以包含多個函式、變數和類別,可以用於封裝相關的程式碼,提高程式碼的可讀性和可維護性。

Python語言的應用

Python語言廣泛應用於多個領域,包括網路開發、資料分析、機器學習、自動化測試等。Python的簡潔易懂的語法和豐富的函式庫和框架,使其成為了一種非常受歡迎的程式語言。

網路開發

Python可以用於網路開發,例如使用Flask或Django框架開發網站。Python也可以用於網路爬蟲,例如使用Scrapy框架爬取網頁資料。

資料分析

Python可以用於資料分析,例如使用Pandas函式庫處理和分析資料,使用Matplotlib函式庫繪製圖表。

機器學習

Python可以用於機器學習,例如使用Scikit-learn函式庫訓練模型,使用TensorFlow或Keras函式庫開發深度學習模型。

自動化測試

Python可以用於自動化測試,例如使用Unittest函式庫編寫單元測試,用Pytest函式庫編寫整合測試。

Python 執行環境設定

在執行 Python 程式碼之前,CPython 執行環境會先設定 Python 執行環境的組態,根據使用者傳入的引數。根據 PEP 587 的定義,執行環境的組態資料儲存於三個地方:

  1. PyPreConfig:預初始化組態資料。
  2. PyConfig:執行環境組態資料。
  3. 編譯後的 CPython 解譯器組態。

預初始化組態

預初始化組態(PyPreConfig)存在於執行環境組態之前,因為其屬性與作業系統或使用者環境有關。PyPreConfig 有三個主要功能:

  1. 設定 Python 的記憶體組態器。
  2. 設定系統的 LC_CTYPE 地區設定或使用者偏好的地區設定。
  3. 設定 UTF-8 模式(PEP 540)。

PyPreConfig 結構包含以下欄位(皆為 int 型別):

  • allocator:選擇記憶體組態器,例如 PYMEM_ALLOCATOR_MALLOC
  • configure_locale:設定 LC_CTYPE 地區設定,如果為 0,則 coerce_c_localecoerce_c_locale_warn 也設為 0。
  • coerce_c_locale:如果為 2,強制使用 C 地區設定;如果為 1,則讀取 LC_CTYPE 地區設定以決定是否強制使用。
  • coerce_c_locale_warn:如果非零,則在強制使用 C 地區設定時發出警告。
  • dev_mode:啟用開發模式。
  • isolated:啟用隔離模式,sys.path 不包含指令碼目錄或使用者的網頁套件目錄。
  • legacy_windows_fs_encoding(僅限 Windows):如果非零,則停用 UTF-8 模式,並將 Python 的檔案系統編碼設為 mbcs。
  • parse_argv:如果非零,則使用命令列引數。
  • use_environment:如果大於 0,則使用環境變數。
  • utf8_mode:如果非零,則啟用 UTF-8 模式。

執行環境組態

執行環境組態(PyConfig)是第二階段的組態,包含多個值,包括:

  • 執行環境旗標,例如除錯和最佳化模式。
  • 執行模式(例如指令碼檔、stdin 或模組)。
  • 進階引數,以 -X <引數> 形式指定。
  • 環境變數,用於設定執行環境。

這些組態資料用於啟用或停用 CPython 執行環境的各個功能。

命令列介面引數

Python 還提供了多個命令列介面引數,例如 -v 旗標,可以啟用詳細輸出模式,顯示模組載入和其他事件的訊息。

組態優先順序:

  1. config->verbose 的初始值為 -1。
  2. 使用 PYTHONVERBOSE 環境變數設定 config->verbose 的值。
  3. 如果環境變數不存在,則使用預設值 -1。
  4. config_parse_cmdline() 函式中,如果指定了命令列旗標,則使用該旗標的值。

這些設定和優先順序機制允許使用者自訂 Python 執行環境的行為。

Python 執行環境組態與輸入處理

Python 的執行環境組態與輸入處理是理解 Python 執行機制的重要組成部分。這包括了組態選項、命令列引數、環境變數等多個方面。

執行環境組態

Python 的執行環境組態可以透過多種方式進行設定,包括命令列引數、環境變數和組態檔案。其中,命令列引數是最直接的設定方式,可以使用 -c 選項執行指定的 Python 程式碼。

命令列引數

命令列引數是設定 Python 執行環境的最直接方式。例如,使用 -c 選項可以執行指定的 Python 程式碼:

$./python -c "print(2 ** 2)"
4

在這個例子中,-c 選項後面的字串是要執行的 Python 程式碼。

環境變數

環境變數也可以用來設定 Python 的執行環境。例如,PYTHONPATH 環境變數可以用來指定 Python 的模組搜尋路徑。

組態檔案

Python 的組態檔案可以用來設定執行環境的各種引數。例如,pyconfig.h 檔案可以用來設定 Python 的編譯時引數。

輸入處理

Python 的輸入處理是指將輸入的程式碼轉換為可執行的模組的過程。這個過程包括了多個步驟,例如讀取輸入程式碼、解析程式碼、編譯程式碼等。

讀取輸入程式碼

Python 的輸入程式碼可以來自於多個源頭,例如檔案、輸入流等。讀取輸入程式碼的過程是由 pymain_main() 函式負責的。

解析程式碼

解析程式碼是指將輸入程式碼轉換為抽象語法樹(AST)的過程。這個過程是由 PyRun_SimpleStringFlags() 函式負責的。

編譯程式碼

編譯程式碼是指將抽象語法樹(AST)轉換為可執行的模組的過程。這個過程是由 PyCompileString() 函式負責的。

執行模組

執行模組是指將編譯好的模組載入到 Python 的執行環境中並執行的過程。這個過程是由 PyEval_EvalCode() 函式負責的。

圖表翻譯:
  graph LR
    A[命令列引數] --> B[環境變數]
    B --> C[組態檔案]
    C --> D[讀取輸入程式碼]
    D --> E[解析程式碼]
    E --> F[編譯程式碼]
    F --> G[執行模組]

這個圖表展示了 Python 的執行環境組態與輸入處理的各個步驟之間的關係。

Python 執行流程與模組載入

Python是一種高階程式語言,具有多種執行方式,包括命令列執行、指令碼執行和模組載入。瞭解Python的執行流程和模組載入機制對於開發者來說至關重要。

執行流程

當您執行Python程式時,Python解譯器會進行以下步驟:

  1. 命令列引數處理:Python解譯器會處理命令列引數,包括指令碼檔案名稱、模組名稱和其他選項。
  2. 模組載入:如果指定了模組名稱,Python會載入該模組。如果指定了指令碼檔案名稱,Python會執行該指令碼。
  3. 程式碼解析:Python解譯器會解析程式碼,包括語法分析和語義分析。
  4. 位元組碼生成:解析後,Python會生成位元組碼(bytecode),這是Python虛擬機器可以執行的中間碼。
  5. 執行:Python虛擬機器會執行位元組碼,完成程式的執行。

模組載入

Python的模組載入機制允許您載入外部模組,以便在您的程式中使用。模組可以是Python檔案、共用函式庫或其他形式的程式碼。

  1. 模組搜尋:當您匯入一個模組時,Python會搜尋該模組在以下位置:
    • 目前工作目錄
    • Python安裝目錄
    • 使用者目錄
    • 其他目錄(由sys.path指定)
  2. 模組載入:如果找到模組,Python會載入該模組,並將其加入到目前的名稱空間中。
  3. 模組初始化:載入後,Python會初始化模組,這包括執行模組的__init__.py檔案(如果存在)。

runpy模組

runpy模組是Python的一個內建模組,負責處理指令碼執行和模組載入。當您執行python -m <module_name>時,runpy模組會被呼叫,以便載入和執行指定的模組。

PyRun_SimpleFileExFlags函式

PyRun_SimpleFileExFlags函式是Python C API的一部分,負責執行Python檔案或指令碼。這個函式會:

  1. 開啟檔案:開啟指定的檔案或指令碼。
  2. 解析程式碼:解析程式碼,包括語法分析和語義分析。
  3. 生成位元組碼:生成位元組碼(bytecode)。
  4. 執行:執行位元組碼,完成程式的執行。

Python 組態和輸入

Python 的組態和輸入過程涉及多個步驟,包括讀取程式碼、詞法分析和解析。詞法分析是將程式碼分解為單個符號或標記的過程,而解析則是將這些標記組織成一個抽象語法樹(AST)。

組態和輸入

Python 的組態可以根據不同的環境和需求進行調整。例如,Python 3.8 在不同的環境中可能有不同的組態,這使得測試和除錯變得複雜。開發者需要檢查環境變數、執行標誌和系統組態屬性,以確保程式碼在不同的環境中正確執行。

詞法分析和解析

詞法分析和解析是編譯過程中的兩個重要步驟。詞法分析將程式碼分解為單個符號或標記,而解析則是將這些標記組織成一個抽象語法樹(AST)。這個過程使得編譯器能夠理解程式碼的結構和含義。

抽象語法樹(AST)

抽象語法樹(AST)是編譯過程中的一個重要資料結構。它代表了程式碼的邏輯結構,使得編譯器能夠分析和最佳化程式碼。AST 由節點和邊組成,每個節點代表一個語法元素,如表示式或陳述式。

Python 的解析過程

Python 的解析過程涉及兩個步驟:建立具體語法樹(CST)和建立抽象語法樹(AST)。CST 是一個有序的樹狀結構,代表了程式碼的語法結構。AST 則是從 CST 中提取出來的邏輯結構,代表了程式碼的含義。

具體語法樹(CST)

具體語法樹(CST)是 Python 解析過程中的第一個步驟。CST 是一個有序的樹狀結構,代表了程式碼的語法結構。它由詞法分析器和解析器共同建立。詞法分析器將程式碼分解為單個符號或標記,而解析器則將這些標記組織成一個樹狀結構。

抽象語法樹(AST)

抽象語法樹(AST)是 Python 解析過程中的第二個步驟。AST 是從 CST 中提取出來的邏輯結構,代表了程式碼的含義。AST 由節點和邊組成,每個節點代表一個語法元素,如表示式或陳述式。

PEG 語法

PEG(Parser Expression Grammar)是一種新的語法,用於 Python 3.9 及後續版本。PEG 語法比傳統的 LL(1) 語法更靈活和強大。PEG 語法使用一種稱為包圍背追蹤(Packrat Parsing)的技術來解析程式碼,這使得解析過程更加高效和準確。

Python 的組態和輸入過程涉及多個步驟,包括讀取程式碼、詞法分析和解析。詞法分析和解析是編譯過程中的兩個重要步驟,分別將程式碼分解為單個符號或標記,並將這些標記組織成一個抽象語法樹(AST)。AST 代表了程式碼的邏輯結構,使得編譯器能夠分析和最佳化程式碼。Python 的解析過程涉及兩個步驟:建立具體語法樹(CST)和建立抽象語法樹(AST)。PEG 語法是一種新的語法,用於 Python 3.9 及後續版本,提供了一種更靈活和強大的解析方式。

程式語法分析

程式語法分析是一種將程式碼分解成最小單位的過程,以便電腦能夠理解和執行程式。這個過程涉及多個階段,包括詞法分析、語法分析和語義分析。

詞法分析

詞法分析是程式語法分析的第一個階段,負責將程式碼分解成最小單位,稱為詞彙(token)。詞彙可以是關鍵字、運算子、識別符號等。例如,在以下程式碼中:

x = 5 + 3

詞法分析器會將程式碼分解成以下詞彙:

  • x:識別符號
  • =:運算子
  • 5:數字
  • +:運算子
  • 3:數字

語法分析

語法分析是程式語法分析的第二個階段,負責將詞彙組合成抽象語法樹(Abstract Syntax Tree, AST)。AST是一種樹狀結構,描述了程式碼的語法結構。例如,在以下程式碼中:

x = 5 + 3

語法分析器會將詞彙組合成以下AST:

  graph LR
    A[指派] --> B[變數]
    A --> C[運算]
    C --> D[數字]
    C --> E[運算子]
    C --> F[數字]

在這個AST中,指派是根節點,變數是左子節點,運算是右子節點。運算節點又包含了數字運算子和另一個數字節點。

語義分析

語義分析是程式語法分析的第三個階段,負責分析AST的語義。語義分析器會檢查AST是否符合語言的語義規則,例如型別檢查、範圍檢查等。例如,在以下程式碼中:

x = 5 + "hello"

語義分析器會檢查x的型別是否與右邊的表示式相容。如果不相容,會報錯。

內容解密:

在這個章節中,我們討論了程式語法分析的基本概念,包括詞法分析、語法分析和語義分析。透過瞭解這些概念,可以幫助我們更好地設計和實作程式語言。

圖表翻譯:

  graph LR
    A[程式碼] --> B[詞法分析]
    B --> C[詞彙]
    C --> D[語法分析]
    D --> E[抽象語法樹]
    E --> F[語義分析]
    F --> G[執行]

這個圖表描述了程式語法分析的流程,從程式碼到執行。每個節點代表了一個階段,箭頭代表了資料的流向。

Python 語法解析:從 Lexical 分析到 Syntax 解析

Python 的語法解析是一個複雜的過程,涉及多個階段。首先,我們需要了解 Lexical 分析的基本單位,即 token。

從程式碼的編譯過程來看,Python 採用了詞法分析、語法分析、編譯成位元組碼,最終由虛擬機器執行的流程。本文深入探討了從語法檔案的重建、新語法規則的測試、標記(Token)與語法的關係、Python 執行環境的設定、輸入處理到程式碼解析的完整流程。理解這些底層機制,對於 Python 開發者而言至關重要,不僅能幫助我們更好地理解 Python 的運作方式,更能提升程式碼的效能和除錯效率。 對於想要深入研究 Python 語言的開發者,建議進一步研究 PEG(Parser Expression Grammar)語法分析器,它比舊有的 LL(1) 解析器更具彈性與效率,也更能適應 Python 語言的發展趨勢。深入理解詞法分析、語法分析和語義分析的流程,可以讓我們更有效地掌握程式碼的結構和邏輯,進而編寫出更優雅、更健壯的 Python 程式。 未來,隨著 Python 語言的持續發展,解析器的效能和功能也將不斷提升,這也將持續推動 Python 生態的繁榮發展。持續關注這些底層技術的演進,將使我們在 Python 開發的道路上始終保持領先。