为什么要编译Python代码?

时间:2009-01-22 22:57:35

标签: python compilation

为什么要编译Python脚本?你可以直接从.py文件运行它们并且它工作正常,那么是否有性能优势?

我还注意到我的应用程序中的某些文件被编译成.pyc而其他文件没有编译,为什么会这样?

10 个答案:

答案 0 :(得分:246)

它被编译为字节码,可以使用更多,更快,更快。

某些文件未编译的原因是每次运行脚本时都会重新编译使用python main.py调用的主脚本。所有导入的脚本都将被编译并存储在磁盘上。

Ben Blank的重要补充:

  

值得注意的是,在跑步时   编译后的脚本有一个更快的启动   时间(因为它不需要   编译),它不运行任何   更快。

答案 1 :(得分:75)

.pyc文件是已经编译为字节码的Python。如果Python找到与您调用的.py文件同名的文件,它会自动运行.pyc文件。

“Python简介”says关于编译的Python文件:

  

程序运行时不会更快   它是从'.pyc'或'.pyo'中读取的   文件比从'.py'读取文件时   文件;唯一更快的事情   关于'.pyc'或'.pyo'文件是   它们加载的速度。

运行.pyc文件的优点是Python在运行之前不必承担编译它的开销。因为Python无论如何都会在运行.py文件之前编译成字节码,除此之外不应该有任何性能改进。

使用已编译的.pyc文件可以获得多少改进?这取决于脚本的功能。对于简单打印“Hello World”的简短脚本,编译可能占总启动和运行时间的很大一部分。但是,对于运行时间较长的脚本,编译脚本相对于总运行时间的成本会降低。

您在命令行上命名的脚本永远不会保存到.pyc文件中。只有那个“主”脚本加载的模块才会以这种方式保存。

答案 2 :(得分:46)

<强>加号:

第一:轻度,失败的混淆。

第二:如果编译导致文件明显变小,您将获得更快的加载时间。对网络很好。

第三:Python可以跳过编译步骤。初始负载更快。适合CPU和网络。

第四:您评论的次数越多,.pyc.pyo文件与源.py文件相比就越小。

第五:手头只有.pyc.pyo文件的最终用户不太可能向他们提供他们忘记告诉你的未恢复的更改所导致的错误。

第六:如果您的目标是嵌入式系统,请获得更小的尺寸 要嵌入的文件可能代表一个重要的优点,并且架构是稳定的,因此下面详述的缺陷不起作用。

顶级汇编

知道你可以用这种方式将顶级python源文件编译成.pyc文件是很有用的:

python -m py_compile myscript.py

删除评论。它使docstrings完好无损。如果你想摆脱docstrings(你可能想认真考虑为什么要这样做),那么就这样编译......

python -OO -m py_compile myscript.py

...您将获得.pyo个文件而不是.pyc个文件;在代码的基本功能方面可以平等分配,但在被剥离的docstrings的大小上更小(如果它首先具有不错的docstrings,则对于后续工作不太容易理解)。但请看下面的缺点三。

请注意,python使用.py文件的日期(如果存在)来决定是否应该执行.py文件而不是.pyc.pyo文件---所以编辑你的.py文件,.pyc.pyo已经过时,你获得的任何好处都会丢失。您需要重新编译它才能再次获得.pyc.pyo权益,例如它们可能会出现。

<强>缺点:

首先:.pyc.pyo文件中有一个“魔术cookie”,表示编译python文件的系统体系结构。如果将其中一个文件分发到不同的环境中类型,它会打破。如果您分发.pyc.pyo而没有关联的.py重新编译或touch,那么它会取代.pyc.pyo,最终用户也无法修复它。

第二:如果使用上面描述的docstrings命令行选项跳过-OO,则没有人能够获取该信息,这可能会使代码更难使用(或者不可能。)

第三:Python的-OO选项也根据-O命令行选项实现了一些优化;这可能会导致操作变化。已知的优化是:

  • sys.flags.optimize = 1
  • assert语句被跳过
  • __debug__ = False

第四:如果你故意让你的python脚本在第一行的#!/usr/bin/python的顺序上可执行,那么.pyc.pyo文件中的内容就会被删除失去了。

第五:有点显而易见,但是如果你编译你的代码,不仅可以影响它的使用,而且其他人从你的工作中学习的可能性也会减少,而且往往是严重的。

答案 3 :(得分:9)

运行已编译的python会有性能提升。但是,当您将.py文件作为导入的模块运行时,python将编译并存储它,并且只要.py文件没有更改,它将始终使用已编译的版本。

使用文件时使用任何交错的语言,过程如下所示:
1.文件由互操作者处理 2.文件编译 3.执行编译代码。

显然通过使用预编译代码可以消除第2步,这适用于python,PHP等。

这是一篇有趣的博客文章,解释了差异http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html 这是一个解释Python编译过程http://effbot.org/zone/python-compile.htm

的条目

答案 4 :(得分:8)

如前所述,将python代码编译为字节码可以提高性能。这通常由python本身处理,仅用于导入的脚本。

您可能想要编译python代码的另一个原因可能是保护您的知识产权不被复制和/或修改。

您可以在Python documentation

中详细了解相关信息

答案 5 :(得分:7)

运行编译脚本时肯定存在性能差异。如果您运行正常的.py脚本,则机器每次运行时都会编译它,这需要时间。在现代机器上,这几乎不可察觉,但随着脚本的增长,它可能会成为一个问题。

答案 6 :(得分:4)

我们使用已编译的代码分发给无权访问源代码的用户。基本上是为了阻止没有经验的程序员在不告诉我们的情况下意外更改或修复错误。

答案 7 :(得分:4)

未涉及的是source-to-source-compiling。例如,nuitka将Python代码转换为C / C ++,并将其编译为直接在CPU上运行的二进制代码,而不是在较慢的虚拟机上运行的Python字节码。

这可以带来显着的加速,或者当您的环境依赖于C / C ++代码时,它可以让您使用Python。

答案 8 :(得分:2)

是的,表现是主要原因,据我所知,唯一的原因。

如果你的某些文件没有被编译,那么Python可能无法写入.pyc文件,可能是因为目录权限或其他原因。或者,未编译的文件可能永远不会被加载...(脚本/模块只有在首次加载时才会被编译)

答案 9 :(得分:1)

初学者假设Python是由.pyc文件编译的。 .pyc文件是已编译的字节码,然后进行解释。因此,如果您之前运行过您的Python代码并且使用.pyc文件,它将在第二次运行得更快,因为它不必重新编译字节码

<强>编译器:     编译器是一段将高级语言翻译成机器语言的代码

<强>口译: 解释器还将高级语言转换为机器可读的二进制等价物。每当解释器获得要执行的高级语言代码时,它就会将代码转换为中间代码,然后再将其转换为机器代码。代码的每个部分都被解释,然后在一个序列中单独执行,并且在代码的一部分中发现错误,它将停止代码的解释而不翻译下一组代码。

<强>来源: http://www.toptal.com/python/why-are-there-so-many-pythons http://www.engineersgarage.com/contribution/difference-between-compiler-and-interpreter