7

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

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

谢谢

完全编译意味着预先编译为本机代码,如 C 或 C++ 或 Lisp。

4

3 回答 3

6

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

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

于 2013-09-01T10:31:19.250 回答
4

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

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

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

于 2013-09-01T10:28:18.533 回答
3

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

严格来说,你不能事先编译 python 程序,因为你在编译时不一定有完整的源代码。eval()众所周知,python 程序可以下载源代码并将其通过。或者以编程方式构造它(在标准库中它实际上在namedtuple().

不过,这不是最大的问题——这些都是边际做法。最大的问题是预先推断数据类型非常困难,在一般情况下可能不可能。如果你有一个函数max(x, y)并且你想把它编译成本地代码,你需要知道 and 的可能类型是什么xy并为每个组合编译一个不同的版本。这可能是个问题。现在,您可以限制某些功能以使此类推断成为可能,然后您就获得了 RPython。

所以,一个python程序是可以编译的,但是很难事先完全做好。

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

  1. PyPy 允许循环运行一段时间而不会产生干扰,同时收集有关其流程的数据(目前为 1000 次迭代)
  2. 根据收集的数据类型和流程,生成和编译优化的汇编代码。
  3. '警卫'被放置到位以检查实际程序流程是否与预测相​​符。
  4. 执行本机代码,直到警卫触发或循环结束。

此外,在开发 PyPy 时,开发人员创建了 RPython,它是 Python 的一个子集,实际上可以完全静态编译。他们主要是通过强制执行早期绑定来实现的。例如,如果您有一个整数变量,则以后不能将其重新用作字符。此外,您不能在列表或其他容器中混合不同的数据类型,等等。

于 2013-09-01T11:13:23.083 回答