简体   繁体   English

什么时候.pyc文件刷新?

[英]When are .pyc files refreshed?

I understand that ".pyc" files are compiled versions of the plain-text ".py" files, created at runtime to make programs run faster. 我知道“.pyc”文件是纯文本“.py”文件的编译版本,在运行时创建以使程序运行得更快。 However I have observed a few things: 但是我发现了一些事情:

  1. Upon modification of "py" files, program behavior changes. 修改“py”文件后,程序行为会发生变化。 This indicates that the "py" files are compiled or at least go though some sort of hashing process or compare time stamps in order to tell whether or not they should be re-compiled. 这表示“py”文件已编译或至少通过某种散列过程或比较时间戳来判断是否应重新编译它们。
  2. Upon deleting all ".pyc" files ( rm *.pyc ) sometimes program behavior will change. 删除所有“.pyc”文件( rm *.pyc )后,程序行为有时会发生变化。 Which would indicate that they are not being compiled on update of ".py"s. 这表明他们没有在更新“.py”时编译。

Questions: 问题:

  • How do they decide when to be compiled? 他们如何决定何时编译?
  • Is there a way to ensure that they have stricter checking during development? 有没有办法确保他们在开发过程中进行更严格的检查?

The .pyc files are created (and possibly overwritten) only when that python file is imported by some other script. 只有当某个其他脚本导入该python文件时,才会创建(并可能覆盖) .pyc文件。 If the import is called, Python checks to see if the .pyc file's internal timestamp is not older than the corresponding .py file. 如果调用导入,Python将检查.pyc文件的内部时间戳是否不早于相应的.py文件。 If it is, it loads the .pyc ; 如果是,则加载.pyc ; if it isn't or if the .pyc does not yet exist, Python compiles the .py file into a .pyc and loads it. 如果不存在或者.pyc尚不存在,Python会将.py文件编译成.pyc并加载它。

What do you mean by "stricter checking"? “更严格的检查”是什么意思?

.pyc files generated whenever the corresponding code elements are imported, and updated if the corresponding code files have been updated. 每当导入相应的代码元素时生成.pyc文件,并且如果相应的代码文件已更新则更新.pyc文件。 If the .pyc files are deleted, they will be automatically regenerated. 如果.pyc文件被删除,它们将自动重新生成。 However, they are not automatically deleted when the corresponding code files are deleted. 但是,删除相应的代码文件时不会自动删除它们。

This can cause some really fun bugs during file-level refactors. 在文件级重构期间,这可能会导致一些非常有趣的错误。

First of all, you can end up pushing code that only works on your machine and on no one else's. 首先,您最终可以推送仅适用于您的计算机而不是其他人的代码。 If you have dangling references to files you deleted, these will still work locally if you don't manually delete the relevant .pyc files because .pyc files can be used in imports. 如果您对已删除的文件有悬空引用,那么如果您不手动删除相关的.pyc文件,这些文件仍可在本地使用,因为.pyc文件可用于导入。 This is compounded with the fact that a properly configured version control system will only push .py files to the central repository, not .pyc files, meaning that your code can pass the "import test" (does everything import okay) just fine and not work on anyone else's computer. 这与以下事实相混淆:正确配置的版本控制系统只会将.py文件推送到中央存储库,而不是.pyc文件,这意味着您的代码可以通过“导入测试”(一切导入正常)就好了而不是在别人的电脑上工作。

Second, you can have some pretty terrible bugs if you turn packages into modules. 其次,如果将软件包转换为模块,则可能会遇到一些非常糟糕的错误。 When you convert a package (a folder with an __init__.py file) into a module (a .py file), the .pyc files that once represented that package remain. 当您将包(具有__init__.py文件的文件夹)转换为模块(.py文件)时,曾经表示该包的.pyc文件仍然存在。 In particular, the __init__.pyc remains. 特别是, __init__.pyc仍然存在。 So, if you have the package foo with some code that doesn't matter, then later delete that package and create a file foo.py with some function def bar(): pass and run: 所以,如果你的包foo包含一些无关紧要的代码,那么稍后删除该包并使用一些函数def bar(): pass创建一个文件foo.py:pass并运行:

from foo import bar

you get: 你得到:

ImportError: cannot import name bar

because python is still using the old .pyc files from the foo package, none of which define bar. 因为python仍在使用foo包中的旧.pyc文件,其中没有一个定义bar。 This can be especially problematic on a web server, where totally functioning code can break because of .pyc files. 这在Web服务器上尤其成问题,因为.pyc文件会导致功能完全正常的代码中断。

As a result of both of these reasons (and possibly others), your deployment code and testing code should delete .pyc files, such as with the following line of bash: 由于这两个原因(可能还有其他原因),您的部署代码和测试代码应删除.pyc文件,例如使用以下bash行:

find . -name '*.pyc' -delete

Also, as of python 2.6, you can run python with the -B flag to not use .pyc files. 此外,从python 2.6开始,您可以使用-B标志运行python以不使用.pyc文件。 See How to avoid .pyc files? 请参阅如何避免.pyc文件? for more details. 更多细节。

See also: How do I remove all .pyc files from a project? 另请参阅: 如何从项目中删除所有.pyc文件?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM