這篇猿人學來聊聊Python的機制,關於pyc檔案的,偏理論技術一點,不知道感興趣的朋友有多少。
我們在執行Python檔案的過程中有時會多出來幾個同名檔案,但是檔案字尾從.py變成了.pyc 。如下圖有三個py檔案,在start_here.py裡import了common.py和unit.py 。
上面是還沒執行前的三個.py檔案,我們python start_here.py執行一下再看看:
執行後看上圖,多出來兩個pyc檔案,分別是common.pyc和unit.pyc 。
1.有沒有好奇為什麼會多出來兩個.pyc檔案?
2.為什麼start_here.py檔案又沒有pyc檔案?
接下來就來說清楚這個兩個問題。
這裡囉嗦一下,我們都知道計算機是不認識你在程式碼裡寫的那一行行字母的,計算機只認二進位制,也只執行二進位制檔案,我們寫的程式碼是需要編譯器編譯成二進位制的。
.pyc檔案是幹什麼的
對於Python來說你寫的Python程式碼在執行python xxx.py時會由Python解析器翻譯成PyCodeObject物件,俗稱位元組碼(byte code),然後交由Python虛擬機器來執行位元組碼(PS:位元組碼才是可執行的)。
在這個過程中這些位元組碼都是在記憶體中的,眾所周知Python的執行效能不如編譯性語言(比如C語言,JAVA …),所以Python在程式執行結束後會把位元組碼寫入到硬碟中,儲存為.pyc檔案,目的是下一次再執行python xxx.py程式時,Python會先在目錄下找xxx.pyc檔案來執行,因為.pyc檔案裡儲存的是位元組碼,所以就節省了Python解析器把xxx.py翻譯成位元組碼的時間,所以就提高了效能。
總結就是.pyc檔案是一個可執行的位元組碼檔案,目的是節省Python解析器翻譯時間,提高執行效率。其實效能只會提高那麼一丟丟,大型專案.py檔案很多的話,猿人學Python測試過節省的時間就多一點。
我們同樣可以像執行py檔案一樣來執行pyc檔案:
什麼時候會生成.pyc檔案
第一次執行python程式後,被import的py檔案會生成.pyc位元組碼檔案,比如我的截圖裡舉的例子,我在start_here.py檔案裡import了common.py和unit.py,執行程式後就生成了common.pyc和unit.pyc,沒有生成start_here.pyc,因為它沒有被import。
當第二次再執行程式時,Python就會拿.pyc檔案和.py檔案的修改時間對比,如果pyc檔案修改時間大於py檔案的話,說明py原始檔沒有被修改,Python就會直接執行.pyc檔案;如果.py檔案的修改時間比.pyc新的話,說明原始檔被修改過,Python就會重新執行.py檔案來重新生成位元組碼。
如果你想讓所有py檔案都生成pyc檔案的話,可以執行:
python -m compileall .
別忘了compileall後面還有一個 . ,會把當前目錄裡py檔案都生成pyc。
其它pyc知識
其實我們安裝的Python第三方庫還是Python自帶的包(模組),都會在該目錄下生成一個’__pycache__’目錄,目錄裡全是該包(模組)的pyc檔案,來看看。
python3.5之後只要你的目錄裡有__main__.py這個檔案,執行命令
python dir(具體的python目錄),就會在該dir下生成__pycache__目錄,裡面是該dir裡的pyc檔案。
另外提供一個騷操作,因為pyc檔案是位元組碼,是二進位制檔案,所以反編譯出原始碼是比較麻煩的,所以如果是專案交付性質,不想交原始碼的話,可以把pyc檔案給對方。只是一個想法,沒有實踐過。
Python知識擴充閱讀:
用pyinstaller打包你的Python程式並繫結CPU
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***