我有 2 个 python 模块,其中一个只支持 Python 2.x,另一个支持 3.x。 不幸的是,我需要一个项目。 我现在的解决方法是让它们作为单独的程序独立运行,并通过套接字模块建立它们的通信。
- 我将以 2 个可执行文件结束,这是我想避免的。
- 两个模块之间的“连接”必须尽可能快。
所以我的问题是,是否有一种方法可以在最后将两者组合成一个可执行文件,以及是否有更好的解决方案来实现快速通信,就像我现在拥有的客户端-服务器结构一样。
最佳答案
确实没有避免这种变通方法的好方法。
从概念上讲,您没有理由不能将两个解释器嵌入到同一个进程中。但实际上,CPython 解释器依赖于一些静态/全局状态。虽然 3.7 在这方面比 3.0 或 2.6 好得多,但这种状态仍然几乎没有被消除。1 而且,C 链接的工作方式,没有办法解决这个问题更换解释器。
此外,嵌入 CPython 并不难,但也不是微不足道的,就像将解释器作为子进程运行一样微不足道——而且它可能比想出一种在子流程之间传递或共享状态的有效方法。
当然除了CPython还有其他的解释器。但是另外一个主要的2.7和3.x版本的实现不太容易嵌入(PyPy),而容易嵌入的两个没有3.x版本,也只能嵌入到另一个VM中,并且可以不要运行 C 扩展模块(Jython 和 IronPython)。 是可以做一些事情,比如使用 JEP 通过 JNI 在 JVM 中嵌入 CPython 3.7,同时也在同一个 JVM 中本地使用 Jython 2.7,但我怀疑这种方法是否适合你。
与此同时,我提到在进程之间传递或共享数据通常并不难。
- 如果您没有那么多数据,通常可以将其通过管道进行腌制。
- 如果您确实有大量数据,它通常或可能以某种结构化形式存储在内存中——numpy 数组、大块 ASCII 或 UTF-8 文本、
ctypes
数组> 结构等——您可以覆盖在mmap
或共享内存段上。 - 或者,当然,您可以提出自己的协议(protocol)并通过(UNIX 或 IP)套接字与其通信。但您不一定要直接跳到该选项。
请注意,multiprocessing
支持前两者——尽管要通过独立的解释器来利用它,您必须深入研究它的源代码并提取您需要的部分。还有第三方库可以提供帮助。 (例如,如果您需要 pickle 一些本地不能 pickle 的东西,答案通常就像“用 dill
替换 pickle
”一样简单。)
<子>1。以各种受限方式运行多个子解释器确实可以处理 mod_wsgi
和 PEP 554 之类的事情。旨在使事情达到这样一种状态,您可以在同一进程中轻松干净地运行多个 3.7 子解释器,但仍然不像完全独立的 CPython 嵌入——子解释器共享一个 GIL、一个循环收集器、一个 atexit
处理程序等
关于Python:在一个项目中使用支持不同 Python 版本的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50194169/