Python:在一个项目中使用支持不同Python版本的模块

4
我有两个 Python 模块,其中一个只支持 Python 2.x 版本,而另一个则支持3.x 版本。 不幸的是,我的项目需要使用这两个版本。 为了解决这个问题,我现在将它们作为单独的程序运行,并通过 socket 模块建立它们之间的通信。
以下是我的问题:
  1. 我最终会得到两个可执行文件,但我希望避免这种情况。
  2. 这两个模块之间的“连接”必须尽可能快。
所以我的问题是:有没有一种方法可以将其合并为一个可执行文件?如果客户端-服务器构造现在存在更好的快速通信解决方案,请告诉我。

把它们中的一个移植到另一个Python版本不是更容易吗? - Stephen Rauch
两个模块的开发者都明确表示不支持另一个版本。我认为如果可能的话,自己去做这件事情会非常复杂。 - Kevin Kreps
1个回答

1

避免这种变通方法确实没有好的办法。

从概念上讲,您可以将两个解释器嵌入同一进程中。但是在实践中,CPython解释器依赖于某些静态/全局状态。虽然3.7比3.0或2.6要好得多,但该状态仍未被完全消除。1而且,由于C链接的工作方式,没有办法在不更改解释器的情况下绕过它。

此外,嵌入CPython并不难,但也不是微不足道的,就像将解释器作为子进程运行那样微不足道,并且可能比想出有效地传递或共享状态的方法更难。

当然,除了CPython之外还有其他的解释器。但是另一个主要实现同时具有2.7和3.x版本的PyPy不容易嵌入,而两个容易嵌入的解释器没有3.x版本,并且也只能嵌入到另一个虚拟机中,不能运行C扩展模块(Jython和IronPython)。可能会像使用JEP通过JNI在JVM中嵌入CPython 3.7并在同一JVM中本地使用Jython 2.7这样做,但我怀疑这种方法是否适合您。
同时,我提到在进程间传递或共享数据通常并不难。
  • 如果你的数据量不是很大,通常可以通过管道传递它的 pickle 对象。
  • 如果你有大量的数据,通常情况下,或者可能会以某种结构化形式存储在内存中,例如numpy数组、ASCII或UTF-8文本块、ctypes结构体数组等,你可以将其叠加在mmap或共享内存段上。
  • 当然,你也可以自己设计协议,并通过(Unix或IP)套接字进行通信。但你不一定非得选择这个选项。

请注意,multiprocessing支持前两项——尽管要想在独立的解释器中利用它,你必须深入其源代码并提取所需的部分。还有第三方库可以帮助你。(例如,如果你需要pickle无法本地pickle的东西,则答案通常就是“用dill替换pickle”。)


1. 在某些受限制的方式下运行多个子解释器可以使用类似于mod_wsgi的工具进行排序,并且PEP 554旨在使事情达到这样的状态,以便您可以轻松、干净地在同一进程中运行多个3.7子解释器,但仍然不像CPython的完全独立嵌入 - 子解释器共享GIL、循环收集器、atexit处理程序等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接