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的語法規則包括變數定義、控制結構、函式定義等。例如,變數定義使用=
運算子,控制結構使用if
、for
、while
等關鍵字,函式定義使用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 的定義,執行環境的組態資料儲存於三個地方:
- PyPreConfig:預初始化組態資料。
- PyConfig:執行環境組態資料。
- 編譯後的 CPython 解譯器組態。
預初始化組態
預初始化組態(PyPreConfig)存在於執行環境組態之前,因為其屬性與作業系統或使用者環境有關。PyPreConfig 有三個主要功能:
- 設定 Python 的記憶體組態器。
- 設定系統的 LC_CTYPE 地區設定或使用者偏好的地區設定。
- 設定 UTF-8 模式(PEP 540)。
PyPreConfig 結構包含以下欄位(皆為 int 型別):
allocator
:選擇記憶體組態器,例如PYMEM_ALLOCATOR_MALLOC
。configure_locale
:設定 LC_CTYPE 地區設定,如果為 0,則coerce_c_locale
和coerce_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
旗標,可以啟用詳細輸出模式,顯示模組載入和其他事件的訊息。
組態優先順序:
config->verbose
的初始值為 -1。- 使用
PYTHONVERBOSE
環境變數設定config->verbose
的值。 - 如果環境變數不存在,則使用預設值 -1。
- 在
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解譯器會進行以下步驟:
- 命令列引數處理:Python解譯器會處理命令列引數,包括指令碼檔案名稱、模組名稱和其他選項。
- 模組載入:如果指定了模組名稱,Python會載入該模組。如果指定了指令碼檔案名稱,Python會執行該指令碼。
- 程式碼解析:Python解譯器會解析程式碼,包括語法分析和語義分析。
- 位元組碼生成:解析後,Python會生成位元組碼(bytecode),這是Python虛擬機器可以執行的中間碼。
- 執行:Python虛擬機器會執行位元組碼,完成程式的執行。
模組載入
Python的模組載入機制允許您載入外部模組,以便在您的程式中使用。模組可以是Python檔案、共用函式庫或其他形式的程式碼。
- 模組搜尋:當您匯入一個模組時,Python會搜尋該模組在以下位置:
- 目前工作目錄
- Python安裝目錄
- 使用者目錄
- 其他目錄(由
sys.path
指定)
- 模組載入:如果找到模組,Python會載入該模組,並將其加入到目前的名稱空間中。
- 模組初始化:載入後,Python會初始化模組,這包括執行模組的
__init__.py
檔案(如果存在)。
runpy模組
runpy
模組是Python的一個內建模組,負責處理指令碼執行和模組載入。當您執行python -m <module_name>
時,runpy
模組會被呼叫,以便載入和執行指定的模組。
PyRun_SimpleFileExFlags函式
PyRun_SimpleFileExFlags
函式是Python C API的一部分,負責執行Python檔案或指令碼。這個函式會:
- 開啟檔案:開啟指定的檔案或指令碼。
- 解析程式碼:解析程式碼,包括語法分析和語義分析。
- 生成位元組碼:生成位元組碼(bytecode)。
- 執行:執行位元組碼,完成程式的執行。
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 開發的道路上始終保持領先。