为什么不能完全编译纯Python?

时间:2013-09-01 10:20:44

标签: python

为什么不能完全编译纯Python?编译或解释是实现的特征,而不是语言。那么不应该有一些完全在手编译为本机代码的Python实现吗?是什么让(纯)Python难以编译?

我知道有像PyPy和Cython这样的东西,但据我所知,那些不是纯Python,需要类型注释等等。

感谢

完全编译的意思,在编译之前编译为本机代码,如C或C ++或Lisp。

3 个答案:

答案 0 :(得分:2)

我认为最大的问题(以及这些实现需要类型注释的原因)是Python规范在很大程度上依赖于延迟语义评估,如函数绑定到执行时间。

即使在某些情况下可以从脚本中完全推断输入,对于一般情况来说,这样做会非常复杂,而依赖于延迟绑定的代码,正如Magnus Hoff在评论中指出的那样,需要嵌入什么相当于生成的可执行文件中的解释器。

编辑:我正在回答隐含的次要问题,即为什么某人没有正面解决这个问题,不同意这种想法在某种程度上是不可能的。例如,C ++运行时执行了许多延迟绑定,但我的感觉是Python做得更多并且稍后执行。

答案 1 :(得分:2)

UPD:感谢Konrad和kqr指出这个答案只讨论C或C ++风格的编译。还有其他方法可以做到这一点,例如Common Lisp。

严格来说,您无法预先编译python程序,因为您不一定在编译时拥有完整的源代码。一个python程序可以下载源代码并通过eval()为我们所知道的所有内容。或者以编程方式构建它(在标准库中它实际上与namedtuple()中完全相同)。

这不是最大的问题 - 这些都是边缘做法。最大的问题是,在一般情况下,预先推断数据类型可能是非常困难的。如果您有一个函数max(x, y)并且想要将其编译为本机代码,则需要知道xy的可能类型,并为每个组合编译不同的版本。这可能是个问题。现在,您可以限制某些功能以使这种推断成为可能,并且您可以获得RPython。

因此,可以编译python程序,但很难事先 完全

这就是为什么有PyPy! PyPy是JIT compiler。它运行代码并在运行时对其进行分析,而不是推断。这就是它实际上只优化循环的原因。以下是它的工作原理(非常粗略):

  1. PyPy允许循环运行一段时间而不会干扰,同时收集有关其流的数据(目前为1000次迭代)
  2. 根据收集的数据类型和流程,生成并编译优化的汇编程序代码。
  3. 'Guards'用于检查实际程序流是否与预测相​​符。
  4. 执行本机代码,直到警卫触发或循环结束。
  5. 此外,在开发PyPy时,开发人员创建了RPython,它是Python的一个子集,实际上可以完全和静态编译。他们主要通过强制执行早期绑定来实现它。例如,如果您有一个整数变量,则不能在以后的行中将其重新用作char。此外,您不能在列表或其他容器中混合使用不同的数据类型,依此类推。

答案 2 :(得分:1)

虚假前提。 Python 可以完全编译,不需要任何类型的注释或任何类型的注释。

此外,PyPy 将Python代码完全编译为机器代码。这不是提前完成的,与可编译性方面无关 - 它只是JIT架构的实现细节。