.pyc文件什么时候刷新?

我知道“.pyc”文件是在运行时创build的纯文本“.py”文件的编译版本,以使程序运行得更快。 但是我观察了一些事情:

  1. 修改“py”文件后,程序行为发生变化。 这表明“py”文件被编译或者至less经过某种哈希处理或比较时间戳,以便判断它们是否应该被重新编译。
  2. 删除所有“.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文件?