【寒假每日一題】總結(第十五天)
__pycache__是什麼
- __pycache__是出現在Python3.2版本之後的特性,專門存放python編譯檔案和原始檔
- Python2.X版本是沒有__pycache__資料夾的,編譯檔案和原始檔存放同目錄
- 如果當前目錄只有執行的指令碼main一個檔案,執行python檔案,則不會生成__pycache__
- 如果當前main檔案中沒有import自定義模組,只import自帶第三方庫,不會產生__pycache__
用python編寫了一個工程,如果import了自定義的第三方模組,在第一次執行後,發現工程根目錄下生成了一個__pycache__資料夾,裡面是和py檔案同名的各種以.cpython-37.pyc結尾的檔案。
cpython-37各項意思,cpython代表的是c語言實現的Python直譯器,-37代表的是3.7版本。
如果import多個自定義的第三方模組,則生成多個以模組命名的pyc
至於pyc,是相當於python的編譯檔案,python位元組碼檔案,執行速度快於py檔案,不能文字檢視內容,可以在釋出時用pyc來代替原始碼py檔案,隱藏原始碼
將py原始碼檔案編譯成位元組碼:
python -m py_compile main.py
if __name__ == '__main__':
作用
模組的呼叫
Python匯入模組時,實際上會把被匯入的模組執行一遍。例如呼叫test.py模組:
def haha():
print("haha")
haha()
主程式main.py:
import test
print("good")
執行結果:
haha
good
如何才能只是單純呼叫而不執行被呼叫模組的程式碼呢?要想被呼叫模組程式碼不被執行,可以使用__name__。如果不涉及模組匯入,name__的值就是__main,如果模組被匯入引用的話,那麼這個模組內的__name__值就是檔案的名字(不帶.py),例如test.py:
def haha(): print("haha") haha() print(__name__)
執行結果為:
haha
__main__
如果test被匯入引用的話,例如test2:
import test
print("good")
執行結果為:
haha
test
good
在被呼叫的模組中,可執行程式碼前加上if name == ‘main’:這麼一句判斷,被呼叫的模組的程式碼就不會被執行。
__pycache__由來
Python程式執行時不需要編譯成二進位制程式碼,而直接從原始碼執行程式。簡單來說是,Python直譯器將原始碼轉換為位元組碼,然後再由直譯器來執行這些位元組碼。
直譯器的具體工作:
- 完成模組的載入和連結;
- 將原始碼編譯為PyCodeObject物件(即位元組碼),寫入記憶體中,供CPU讀取;
- 從記憶體中讀取並執行,結束後將PyCodeObject寫回硬碟當中,也就是複製到.pyc或.pyo檔案中,以儲存當前目錄下所有指令碼的位元組碼檔案。
之後若再次執行該指令碼,它先檢查【本地是否有上述位元組碼檔案】和【該位元組碼檔案的修改時間是否在其原始檔之後】,是就直接執行,否則重複上述步驟。
__pycache__的意義
第一次執行程式碼的時候,Python直譯器已經把編譯的位元組碼放在__pycache__資料夾中,這樣以後再次執行的話,如果被呼叫的模組未發生改變,那就直接跳過編譯這一步,直接去__pycache__資料夾中去執行相關的*.pyc檔案,大大縮短了專案執行前的準備時間。