为什么不能完全编译纯Python?编译或解释是实现的特征,而不是语言。那么不应该有一些完全在手编译为本机代码的Python实现吗?是什么让(纯)Python难以编译?
我知道有像PyPy和Cython这样的东西,但据我所知,那些不是纯Python,需要类型注释等等。
感谢
完全编译的意思,在编译之前编译为本机代码,如C或C ++或Lisp。
答案 0 :(得分:2)
我认为最大的问题(以及这些实现需要类型注释的原因)是Python规范在很大程度上依赖于延迟语义评估,如函数绑定到执行时间。
即使在某些情况下可以从脚本中完全推断输入,对于一般情况来说,这样做会非常复杂,而依赖于延迟绑定的代码,正如Magnus Hoff在评论中指出的那样,需要嵌入什么相当于生成的可执行文件中的解释器。
编辑:我正在回答隐含的次要问题,即为什么某人没有正面解决这个问题,不同意这种想法在某种程度上是不可能的。例如,C ++运行时执行了许多延迟绑定,但我的感觉是Python做得更多并且稍后执行。
答案 1 :(得分:2)
严格来说,您无法预先编译python程序,因为您不一定在编译时拥有完整的源代码。一个python程序可以下载源代码并通过eval()
为我们所知道的所有内容。或者以编程方式构建它(在标准库中它实际上与namedtuple()
中完全相同)。
这不是最大的问题 - 这些都是边缘做法。最大的问题是,在一般情况下,预先推断数据类型可能是非常困难的。如果您有一个函数max(x, y)
并且想要将其编译为本机代码,则需要知道x
和y
的可能类型,并为每个组合编译不同的版本。这可能是个问题。现在,您可以限制某些功能以使这种推断成为可能,并且您可以获得RPython。
因此,可以编译python程序,但很难事先 和完全。
这就是为什么有PyPy! PyPy是JIT compiler。它运行代码并在运行时对其进行分析,而不是推断。这就是它实际上只优化循环的原因。以下是它的工作原理(非常粗略):
此外,在开发PyPy时,开发人员创建了RPython,它是Python的一个子集,实际上可以完全和静态编译。他们主要通过强制执行早期绑定来实现它。例如,如果您有一个整数变量,则不能在以后的行中将其重新用作char。此外,您不能在列表或其他容器中混合使用不同的数据类型,依此类推。
答案 2 :(得分:1)
虚假前提。 Python 可以完全编译,不需要任何类型的注释或任何类型的注释。
此外,PyPy 将Python代码完全编译为机器代码。这不是提前完成的,与可编译性方面无关 - 它只是JIT架构的实现细节。