簡體   English   中英

什么時候.pyc文件刷新?

[英]When are .pyc files refreshed?

我知道“.pyc”文件是純文本“.py”文件的編譯版本,在運行時創建以使程序運行得更快。 但是我發現了一些事情:

  1. 修改“py”文件后,程序行為會發生變化。 這表示“py”文件已編譯或至少通過某種散列過程或比較時間戳來判斷是否應重新編譯它們。
  2. 刪除所有“.pyc”文件( rm *.pyc )后,程序行為有時會發生變化。 這表明他們沒有在更新“.py”時編譯。

問題:

  • 他們如何決定何時編譯?
  • 有沒有辦法確保他們在開發過程中進行更嚴格的檢查?

只有當某個其他腳本導入該python文件時,才會創建(並可能覆蓋) .pyc文件。 如果調用導入,Python將檢查.pyc文件的內部時間戳是否不早於相應的.py文件。 如果是,則加載.pyc ; 如果不存在或者.pyc尚不存在,Python會將.py文件編譯成.pyc並加載它。

“更嚴格的檢查”是什么意思?

每當導入相應的代碼元素時生成.pyc文件,並且如果相應的代碼文件已更新則更新.pyc文件。 如果.pyc文件被刪除,它們將自動重新生成。 但是,刪除相應的代碼文件時不會自動刪除它們。

在文件級重構期間,這可能會導致一些非常有趣的錯誤。

首先,您最終可以推送僅適用於您的計算機而不是其他人的代碼。 如果您對已刪除的文件有懸空引用,那么如果您不手動刪除相關的.pyc文件,這些文件仍可在本地使用,因為.pyc文件可用於導入。 這與以下事實相混淆:正確配置的版本控制系統只會將.py文件推送到中央存儲庫,而不是.pyc文件,這意味着您的代碼可以通過“導入測試”(一切導入正常)就好了而不是在別人的電腦上工作。

其次,如果將軟件包轉換為模塊,則可能會遇到一些非常糟糕的錯誤。 當您將包(具有__init__.py文件的文件夾)轉換為模塊(.py文件)時,曾經表示該包的.pyc文件仍然存在。 特別是, __init__.pyc仍然存在。 所以,如果你的包foo包含一些無關緊要的代碼,那么稍后刪除該包並使用一些函數def bar(): pass創建一個文件foo.py:pass並運行:

from foo import bar

你得到:

ImportError: cannot import name bar

因為python仍在使用foo包中的舊.pyc文件,其中沒有一個定義bar。 這在Web服務器上尤其成問題,因為.pyc文件會導致功能完全正常的代碼中斷。

由於這兩個原因(可能還有其他原因),您的部署代碼和測試代碼應刪除.pyc文件,例如使用以下bash行:

find . -name '*.pyc' -delete

此外,從python 2.6開始,您可以使用-B標志運行python以不使用.pyc文件。 請參閱如何避免.pyc文件? 更多細節。

另請參閱: 如何從項目中刪除所有.pyc文件?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM