当前位置: 首页 > 科技观察

Python编程语言的核心是什么?

时间:2023-03-13 20:34:31 科技观察

为什么要问这个问题?众所周知,我们需要WebAssembly的Python实现。它不仅将Python引入浏览器,而且由于iOS和Android都支持将JavaScript作为应用程序的一部分运行,因此它也将Python引入了移动设备。这一切都让我兴奋。但是当想到创建一个新的Python实现的艰巨任务时,我的大脑也开始发问:Python到底是什么?我们与CPython一起生活了这么久,我怀疑我们中的大多数人只是简单地认为“Python==CPython”。PyPy试图兼容以实现CPython的实现细节。基本上,我所知道的大多数Python实现都试图通过CPython的测试套件并尽可能与CPython兼容。这是令人生畏的。CPython的Python实现非常动态,并公开了许多只有在使用解释器实现Python时才有意义的东西。例如,PyPy有一个用于JIT的基线解释器,但是有很多东西可以在Python中使用来强制PyPy关闭JIT并坚持使用字节码。REPL本身就使事情变得非常动态,因为解释器会立即动态解析、编译和执行进入REPL的所有内容。这让我开始思考Python究竟是什么?语言的核心是什么?所有的Python实现都需要覆盖什么样的基线,才能真正称得上是人们仍然能够认可的Python实现?或者从我的角度来看,直接将Python编译成WebAssembly还算得上是Python实现,需要实现多少?Python需要REPL吗?真正让我想到这个的是当我开始思考如何将Python编译为WebAssembly时?没有实现另一个解释器,但它实际上从Python源代码发出静态WebAssembly,并且仍然合理地称为“Python”。我知道的一件事是,通过eval()或compile()进行动态编译可能并不容易,因为WebAssembly的安全模型会在加载时验证模块。这意味着在其他代码的内存空间中没有用于运行任意代码的结构,这会使REPL实现变得棘手。但这让我开始思考:Python真的需要REPL吗?别误会,这很方便,但是如果一个实现没有REPL,那不就是Python了吗?我认为没有答案的Python仍然是Python,它只是缺少一个(可能是关键的)特性。这让我开始思考Python的哪些部分需要被视为“Python”?没有本地人你能活吗?这是一个非常动态的东西,能够任意收集所有定义的局部变量和它们的值到一个字典中。如果你在像CPython这样的解释器中,你只需要从当前执行帧中获取一些局部变量。但是在编译语言中,它的工作量更大,因为您必须知道何时收集所有这些信息,因为在调用local()时它不一定无处不在。或者人们如何覆盖local()本身?在CPython中,这没什么大不了的,因为内置模块有一个__dict__,您可以覆盖它,它会简单地传播到任何未来的调用。但是在编译语言中,做这个检查需要更多的努力,而且这样的检查最终会降低性能。sys.settrace()怎么样?它实际上触发了每个字节码的回调,如果代码被编译则不能正常工作。您可以通过检查是否在每一行之后设置了跟踪函数来伪造它,但是当您大多数时候没有设置这样的挂钩时,这似乎有点过分(尽管它可能是使用此支持徽标进行编译的编译器)。sys._getframe()怎么样?编译型语言不一定能直接访问执行框架,所以你需要费心去模拟它?由于任何函数都可以请求执行帧,因此您需要准备好按需提供它们。如您所见,Python中有很多东西使编译变得困难(因此Nuitka更有能力应对这一挑战)。但我打赌你不会在99.9%的时间里使用我上面提到的东西,所以如果一个实现不使用它们,它仍然可以被认为是“Python”吗?多少兼容性有用?这个问题我没有很好的答案。但它的回答说明了实现Python的困难及其与现有软件的兼容性。我想说的是,我认为WebAssembly不需要支持很多Python软件才有用。WebAssembly可以访问Rust和JavaScript等其他语言生态系统,因此用其他语言实现您需要的东西的机会肯定大于零。我不知道开发一个将Python代码直接转换为WebAssembly并为性能牺牲一些兼容性的编译器是否有意义。开发一个针对WebAssembly设计的解释器,同时保持与现有代码的兼容性可能是有意义的。在他们的WebAssembly工作中简单地支持RustPython可能是有意义的。也许Pyodide可以帮助我们实现目标。我不认为这两种可能性中的任何一种在本质上都是错误的,它可能只是归结为人们足够感兴趣并认为它对其他人有用的可能性。