'Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理'

Python 分佈式計算 軟件測試開發技術棧 2019-09-18
"
"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

testops.py

再來看一下 testops_imported.py 模塊,該模塊中導入了 testops模塊,如下圖:

"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

testops.py

再來看一下 testops_imported.py 模塊,該模塊中導入了 testops模塊,如下圖:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

我們先執行 testops.py,看下目錄,目錄內無任何無變化。

"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

testops.py

再來看一下 testops_imported.py 模塊,該模塊中導入了 testops模塊,如下圖:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

我們先執行 testops.py,看下目錄,目錄內無任何無變化。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

然後再執行 testops_imported.py,我們查看下該目錄發生了哪些變化,如下:

"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

testops.py

再來看一下 testops_imported.py 模塊,該模塊中導入了 testops模塊,如下圖:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

我們先執行 testops.py,看下目錄,目錄內無任何無變化。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

然後再執行 testops_imported.py,我們查看下該目錄發生了哪些變化,如下:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

可以發現,在執行 testops_imported.py之後,目錄中多了一個 __pycache__ 目錄,看下該目錄中有哪些文件,如下,執行 testops_imported.py,多了一個 testops.cpython-37.pyc 文件,這是為什麼呢?

"
Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

由於最近一位同學在做分佈式計算時,部分模塊只把 pyc文件拷貝部署至遠程計算節點,導致主節點程序更新後,計算節點拋出了錯誤異常,於是有了這篇文章...


示例

如下,有兩個py模塊,testops.pytestops_imported.py模塊。我們先來看 testops.py模塊。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

testops.py

再來看一下 testops_imported.py 模塊,該模塊中導入了 testops模塊,如下圖:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

我們先執行 testops.py,看下目錄,目錄內無任何無變化。

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

然後再執行 testops_imported.py,我們查看下該目錄發生了哪些變化,如下:

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理

可以發現,在執行 testops_imported.py之後,目錄中多了一個 __pycache__ 目錄,看下該目錄中有哪些文件,如下,執行 testops_imported.py,多了一個 testops.cpython-37.pyc 文件,這是為什麼呢?

Python什麼情況下會生成 pyc文件?通過pyc文件瞭解Python運行原理


Python運行原理

每一個 .py 文件都會作為 Python中的一個模塊,如上例子中,包含了 testops.pytestops_imported.py 兩個模塊,其中 testops_imported作為程序運行的入口(導入了testops模塊)。

運行 testops_imported.py後,會激活 Python 的解釋器,將 testops模塊編譯成一個字節碼對象(PyCodeObject)並保存在內存當中(方便CPU讀取,提高程序運行效率),接下來由 Python 虛擬機來執行字節碼指令。當Python程序運行結束時,Python解釋器則將字節碼對象持久化至pyc文件中(.pyc 文件是字節碼對象在硬盤上的表現形式)。

當此模塊程序再次運行時,首先程序會在硬盤中尋找 pyc文件,如果找到,則直接將字節碼對象加載到內存中,否則就重複上面的過程。

也就是說,我們之所以要把 py文件編譯成 pyc文件,其最大的好處在於我們在重複運行程序時,不需要重新對該模塊進行重複的編譯。


那麼字節碼對象包含什麼呢?

一個字節碼對象文件(.pyc)包含了三部分信息:Python 的 magic number創建時間以及 PyCodeObject對象

magic number 是 Python 定義的一個整數值。一般來說,不同版本的 Python 實現都會定義不同的 magic number,這個值是用來保證 Python 兼容性的。不同版本的 Python 定義的字節碼指令可能會不同,如果不做檢查,執行的時候就可能出錯。比如要限制由低版本編譯的 pyc 文件不能讓高版本的 Python 程序來執行,只需要檢查 magic number 不同就可以了。

創建時間是用來判斷 pyc文件是否有效,每次在載入之前都會先校驗 py文件和 pyc文件的最後修改日期,如果不一致則重新生成一份pyc文件(詳見 import.py源碼 ),避免了修改源代碼後與本地字節碼文件產生衝突。


為什麼有時執行test.py模塊,沒有生成.pyc文件呢?

首先,既然 pyc存在意義是重複運行的時候免去編譯操作,那麼需要編譯成pyc文件的應該是那些可以重用的模塊。所以Python的解釋器認為:只有import進來的模塊,才是需要被重用的模塊。這也是為什麼執行 testops_imported.py模塊時,只生成了被導入的 testops.py模塊的pyc文件的原因。

日常程序設計時,公共通用的方法封裝成單獨的模塊,通過導入模塊被使用,有利於提高代碼運行效率,當然這一般也不會是什麼瓶頸。。。


"

相關推薦

推薦中...