为什么主要的可运行的Python脚本不能编译成像pyc文件一样的模块?
我明白,当你导入一个模块时,该文件被编译成一个.pyc
文件使其更快? 为什么主文件也没有编译成.pyc
? 这会减慢速度吗? 保持主文件尽可能小还是不重要?
当一个模块被加载时,py文件被“字节编译”为pyc文件。 时间戳被logging在pyc文件中。 这样做并不是为了让它运行得更快,而是加载速度更快。 因此,加载它们时,“字节编译”模块是有意义的。
[编辑:包括笔记,参考]
从“字节代码编译”的PEP 3147:
CPython将其源代码编译为“字节码”,出于性能方面的考虑,只要源文件发生更改,就会将该字节码caching在文件系统上。 这使得加载Python模块的速度更快,因为编译阶段可以被绕过。 当您的源文件是foo.py时,CPython将字节码caching在源旁边的foo.pyc文件中。
如何跟踪Python版本和“py”文件更改的字节码编译文件:
它还在编译的字节码“.pyc”文件中插入一个幻数。 只要Python更改字节码格式,通常在主要版本中就会更改。
这可以确保为以前版本的VM构build的pyc文件不会造成问题。 时间戳用于确保pyc文件与用来创build它的py文件相匹配。 当幻数或时间戳不匹配时,py文件被重新编译并写入一个新的pyc文件。
Python主要版本中“pyc”文件不兼容。 当Pythonfind一个不匹配幻数的pyc文件时,它会回落到重新编译源代码的较慢过程。
这就是为什么如果你简单地分发为相同的平台编译的“.pyc”文件将不再工作,如果python版本改变。
在坚果壳
如果有一个字节编译的文件“.pyc”,它的时间戳表明它是最近的,那么它将被加载其他明智的python将回退加载“.py”文件的较慢的方法。 “.py”文件的执行性能不受影响,但“.pyc”文件的加载速度比“.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.
也就是说,如果你有一个很大的脚本文件X.py,模块化它并将内容移动到其他模块,则可以利用字节码编译文件的较低的加载时间。
另一个推论是,模块往往比脚本或主文件更稳定。 因此它根本不是字节编译的。
参考
编译主脚本会对/usr/bin
脚本造成/usr/bin
。 .pyc文件生成在同一个目录中,从而污染公共位置。