毫無疑問,Python 已經成為當下最主流的語言之一,如果你只是會用,那么很難和其他人拉開差距。但如果你知道 Python 解釋器的底層原理,比如:
那么你在面試的時候一定能讓面試官眼前一亮,并且也能寫出更好、更優雅的代碼,這也是我們為什么要剖析 Python 解釋器源碼。可 Python 解釋器的源碼行數有五十多萬行,該怎么入手呢?不用擔心,本系列就來抽絲剝繭,帶你近距離觀察 Python 解釋器這座宏偉大廈。
注:官方 Python 解釋器由 C 語言編寫,我們稱之為 CPython。想要讀懂它,需要有一定的 C 語言基礎,當然我也會給出詳細的注釋。
本系列力求詳細、精致,在介紹源碼時會給出大量的注釋和清晰的圖表,并且我不僅僅會介紹源碼實現,還會穿插大量的 Python 普通知識。因為 Python 解釋器由 C 語言編寫,想要讀懂它,需要有一定的 C 語言基礎。而本系列則確保,不管你 C 語言的水平如何,讀了之后都能有所收獲。
接下來登錄 Python 官網 www.python.org 下載 CPython。
圖片
目前 Python 的最新版本是 3.12.3,我們點擊它。當然隨著時間的推移,Python 也會進行更新。
圖片
再點擊 Gzipped source tarball 即可下載指定版本的源碼。
壓縮包下載下來之后解壓,即可得到整個 CPython 工程項目,我們看看它長什么樣子?
圖片
解釋一下每個目錄的作用。
存儲 Python 文檔的源文件(.rst),用于編譯之后生成官方文檔。
負責定義 Python 的語法規則。
包含 Python 所有公開的頭文件,這些文件定義了 Python 的 C API,在編寫擴展模塊和嵌入式開發時會用到。
Python 的標準庫,對于那些不影響性能的功能會用 Python 編寫,然后放在 Lib 目錄下面。
Python 的內置庫,這些庫都是用 C 編寫的,編譯之后會內嵌在解釋器里面。我們舉個例子:
import random, _randomimport re, _sreimport io, _ioimport ast, _ast
以 random 為例,它是用來生成隨機數的,和性能密切相關。所以它的核心功能由 C 編寫,編譯之后內嵌在解釋器里,模塊名為 _random。只不過 Python 又封裝了一個 random,在內部會導入 _random,像 re 和 _sre、asyncio 和 _asyncio 都是類似的關系。
Modules 目錄里面實現了大量和性能相關的模塊,比如 sys、time、gc 等等,我們后續再聊。
包含 Python 內置數據結構的底層實現,像字典、列表、元組、函數等,底層實現都定義在 Objects 目錄中。
負責 Python 編譯器的具體實現,雖然 Python 是解釋型語言,但也是要經過編譯的。編譯的結果為 PyCodeObject 對象,它里面包含了要執行的字節碼,編譯完之后會交給虛擬機執行。
所以 Python 解釋器 = Python 編譯器 + Python 虛擬機。
Python 虛擬機的具體實現,字節碼的執行、執行環境的管理等都在里面。
用于 Mac OS X 平臺的特定工具和腳本。
包含各種雜項文件,如配置腳本、工具等。
專為 Windows 平臺編寫的配置文件和特定擴展。
用于在 Windows 上編譯 Python 的項目文件。
包含 Python 其它可執行文件(如 IDLE)的源代碼。
包含用 Python 編寫的各種腳本和工具,幫助開發和維護 Python。
以上就是 CPython 的源碼結構,對它有一個基本的認識有助于我們后續的源碼學習。
介紹源碼結構時我們說 Python 解釋器 = Python 編譯器 + Python 虛擬機,那當解釋器執行 py 文件時都經歷了哪些過程呢?
圖片
Read File、Scanner、Parser、Compiler 都是由 Python 編譯器負責的,Code Eval 則由 Python 虛擬機負責。
因此 Python 雖然是解釋型語言,但也有編譯的過程。源代碼會被編譯器編譯成 PyCodeObject 對象,然后再交給虛擬機來執行。而之所以要存在編譯,是為了讓虛擬機能更快速地執行,比如在編譯階段常量都會提前分配好,而且還可以盡早檢測出語法上的錯誤。
而 Python 編譯器和 Python 虛擬機組合起來,便是 Python 解釋器。
圖片
如果你了解 Java,那么應該知道 Java 也有編譯器和虛擬機。只不過 Java 的編譯器和虛擬機是分開的,而 Python 則是整合在一起的。
不過在后續介紹 Python 源碼的時候,我們暫不涉及 Python 編譯器的部分,也就是 Parser 目錄里面的代碼不做分析,因為涉及到編譯原理。而且編譯這一過程也不是 Python 語言獨有的,任何一門編程語言、當然還有 SQL 都會涉及到編譯。所以探究 Python 代碼的編譯過程沒太大意義,我們的重點是 Python 代碼的編譯結果,以及虛擬機是如何執行的?
當然如果大家對編譯過程感興趣,我們后面也會介紹一下這方面的內容。舉個例子,我們來替換掉 Python 的幾個關鍵字。
圖片
Python 源碼的分詞,語法解析等均由 Parser 目錄負責。
圖片
比如 tokenizer.c 負責分詞,parser.c 負責語法解析,感興趣可以看一下,但不建議花太多時間。因為這個過程對深入 Python 沒多大用,并且 parser.c 的代碼行數多達 4w 多行,讀起來也很痛苦。
本文鏈接:http://www.tebozhan.com/showinfo-26-87264-0.html為什么要看 Python 源碼?它的結構長什么樣子?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com