1. 程式人生 > 其它 >【寒假每日一題】總結(第十五天)

【寒假每日一題】總結(第十五天)

技術標籤:Pythonpython

__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直譯器將原始碼轉換為位元組碼,然後再由直譯器來執行這些位元組碼。

直譯器的具體工作:

  1. 完成模組的載入和連結;
  2. 將原始碼編譯為PyCodeObject物件(即位元組碼),寫入記憶體中,供CPU讀取;
  3. 從記憶體中讀取並執行,結束後將PyCodeObject寫回硬碟當中,也就是複製到.pyc或.pyo檔案中,以儲存當前目錄下所有指令碼的位元組碼檔案。

之後若再次執行該指令碼,它先檢查【本地是否有上述位元組碼檔案】和【該位元組碼檔案的修改時間是否在其原始檔之後】,是就直接執行,否則重複上述步驟。

__pycache__的意義

第一次執行程式碼的時候,Python直譯器已經把編譯的位元組碼放在__pycache__資料夾中,這樣以後再次執行的話,如果被呼叫的模組未發生改變,那就直接跳過編譯這一步,直接去__pycache__資料夾中去執行相關的*.pyc檔案,大大縮短了專案執行前的準備時間。