为什么主要的可运行 Python 脚本没有像模块一样编译为 pyc 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3878479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are main runnable Python scripts not compiled to pyc files like modules?
提问by George41
I understand that when you import a module, that file is compiled into a .pycfile to make it faster? Why is the main file also not compiled to a .pyc? Does this slow things down? Would it be better to keep the main file as small as possible then, or does it not matter?
我知道当你导入一个模块时,那个文件被编译成一个.pyc文件以使其更快?为什么主文件也没有编译成.pyc? 这会减慢速度吗?那么保持主文件尽可能小会更好,还是无关紧要?
采纳答案by pyfunc
When a module is loaded, the py file is "byte compiled" to pyc files. The time stamp is recorded in pyc files. This is done not to make it run faster but to load faster.Hence, it makes sense to "byte compile" modules when you load them.
当一个模块被加载时,py 文件被“字节编译”为 pyc 文件。时间戳记录在 pyc 文件中。 这样做不是为了让它运行得更快,而是为了更快地加载。因此,在加载模块时“字节编译”模块是有意义的。
[Edit : To include notes, references]
[编辑:包括注释,参考]
From PEP 3147 on "Byte code compilation":
从 PEP 3147 关于“字节码编译”:
CPython compiles its source code into "byte code", and for performance reasons, it caches this byte code on the file system whenever the source file has changes. This makes loading of Python modules much faster because the compilation phase can be bypassed. When your source file is foo.py, CPython caches the byte code in a foo.pyc file right next to the source.
CPython 将其源代码编译为“字节码”,并且出于性能原因,只要源文件发生更改,它就会将此字节码缓存在文件系统上。这使得 Python 模块的加载速度更快,因为可以绕过编译阶段。当你的源文件是 foo.py 时,CPython 将字节码缓存在源文件旁边的 foo.pyc 文件中。
How byte code compiled files are tracked with respect to Python version and "py" file changes:
如何根据 Python 版本和“py”文件更改跟踪字节码编译文件:
It also inserts a magic number in the compiled byte code ".pyc" files.
This changes whenever Python changes the byte code format, usually in major releases.
This ensures that pyc files built for previous versions of the VM won't cause problems.
The timestamp is used to make sure that the pyc file match the py file that was
used to create it. When either the magic number or timestamp do not match,
the py file is recompiled and a new pyc file is written.
它还在编译后的字节码“.pyc”文件中插入一个幻数。每当 Python 更改字节码格式时,这都会发生变化,通常是在主要版本中。
这可确保为以前版本的 VM 构建的 pyc 文件不会导致问题。时间戳用于确保 pyc 文件与用于创建它的 py 文件匹配。当幻数或时间戳不匹配时,重新编译 py 文件并写入新的 pyc 文件。
"pyc" files are not compatible across Python major releases. When Python finds a pyc file with a non-matching magic number, it falls back to the slower process of recompiling the source.
“pyc”文件在 Python 主要版本之间不兼容。当 Python 找到具有不匹配幻数的 pyc 文件时,它会退回到重新编译源的较慢过程。
Thats the reason, if you simply distribute the ".pyc" files compiled for the same platform will not work any more, if the python version changes.
这就是原因,如果您只是分发为同一平台编译的“.pyc”文件,如果python版本发生变化,将不再起作用。
In Nutshell
简而言之
If there is a byte compiled file ".pyc" and it's timestamp indicates that it is recent then it will be loaded up other wise python will fallback on the slower approach of loading the ".py" files. The execution performance of the ".py" file is not affected but the loading of the ".pyc" files is faster than ".py" files.
如果有一个字节编译文件“.pyc”并且它的时间戳表明它是最近的,那么它将被加载,否则python将回退到加载“.py”文件的较慢方法。“.py”文件的执行性能不受影响,但“.pyc”文件的加载速度比“.py”文件快。
Consider executing a.py which imports b.py
考虑执行导入 b.py 的 a.py
Typical total performance = loading time (A.py) + execution time (A.py) +
loading time (B.py) + execution time (B.py)
Since loading time (B.pyc) < loading time (B.py)
You should see a better performance by using the byte compiled "pyc" files.
That said, if you have a large script file X.py, modularizing it and moving contents to other modules results in taking advantage of lower load time for byte code compiled file.
也就是说,如果您有一个大型脚本文件 X.py,对其进行模块化并将内容移动到其他模块可以利用字节码编译文件的较低加载时间。
Another inference is that modules tend to be more stable than the script or the main file. Hence it is not byte compiled at all.
另一个推论是模块往往比脚本或主文件更稳定。因此它根本不是字节编译的。
References
参考
回答by Ignacio Vazquez-Abrams
Compiling the main script would be annoying for scripts in e.g. /usr/bin. The .pyc file is generated in the same directory, thus polluting the public location.
编译主脚本对于例如/usr/bin. .pyc 文件生成在同一个目录下,从而污染了公共位置。

