.pyc文件什么时候刷新?
我知道“.pyc”文件是在运行时创build的纯文本“.py”文件的编译版本,以使程序运行得更快。 但是我观察了一些事情:
- 修改“py”文件后,程序行为发生变化。 这表明“py”文件被编译或者至less经过某种哈希处理或比较时间戳,以便判断它们是否应该被重新编译。
- 删除所有“.pyc”文件(
rm *.pyc
)后,有时程序行为会改变。 这将表明他们没有被编译更新“.py”。
问题:
- 他们如何决定何时编译?
- 有没有办法确保他们在开发过程中有更严格的检查?
只有当python文件被其他脚本导入时, .pyc
文件才会被创build(也可能被覆盖)。 如果调用导入,Python将检查.pyc
文件的内部时间戳是否与相应的.py
文件匹配。 如果是,则加载.pyc
; 如果没有,或者.pyc
不存在,Python会将.py
文件编译成一个.pyc
文件并加载它。
你是什么意思“严格检查”?
每当导入相应的代码元素时生成.pyc文件,如果相应的代码文件已经更新,则更新.pyc文件。 如果.pyc文件被删除,它们将被自动重新生成。 但是,当相应的代码文件被删除时,它们不会被自动删除。
这可能会导致一些真正有趣的错误在文件级重构。
首先,你最终可以推送只能在你的机器上和别人的机器上运行的代码。 如果您有对您删除的文件的悬挂引用,如果您没有手动删除相关的.pyc文件,这些文件仍然可以在本地工作,因为可以在导入中使用.pyc文件。 这是因为一个正确configuration的版本控制系统只会将.py文件推送到中央存储库,而不是.pyc文件,这意味着你的代码可以通过“导入testing”(一切都可以导入),而不是在别人的电脑上工作。
其次,如果将软件包转换为模块,则可能会出现一些非常糟糕的错误。 将包(具有__init__.py
文件的文件夹)转换为模块(.py文件)时,曾经表示该包的.pyc文件保留。 特别是, __init__.pyc
保持不变。 所以,如果你有一些与代码无关的包foo,那么稍后删除这个包并用def bar(): pass
函数创build一个文件foo.py:pass and run:
from foo import bar
你得到:
ImportError: cannot import name bar
因为python仍然使用foo包中的旧的.pyc文件,其中没有一个定义bar。 在web服务器上,这可能会特别成问题,因为.pyc文件会导致完全正常运行的代码可能中断。
由于这两个原因(也可能是其他原因),您的部署代码和testing代码应删除.pyc文件,例如使用以下bash行:
find . -name '*.pyc' -delete
另外,从Python 2.6开始,你可以运行带有-B
标志的python来不使用.pyc文件。 请参阅如何避免.pyc文件? 更多细节。
另请参阅: 如何从项目中删除所有.pyc文件?