python - 使用不同的 Python 版本调用 Python 函数最接近的方法是什么?

标签 python compatibility popen

假设我有两个文件:

# spam.py
import library_Python3_only as l3

def spam(x,y)
    return l3.bar(x).baz(y)

# beans.py
import library_Python2_only as l2

...

现在假设我希望从 beans 中调用 spam。这不是直接可能的,因为这两个文件都依赖于不兼容的 Python 版本。当然,我可以 Popen 一个不同的 python 进程,但是我怎样才能传入参数并检索结果而没有太多的流解析痛苦呢?

最佳答案

这是我实际测试过的使用 subprocesspickle 的完整示例实现。请注意,您需要在 Python 3 端显式使用协议(protocol)版本 2 进行酸洗(至少对于 Python 3.5.2 和 Python 2.7.3 的组合)。

# py3bridge.py

import sys
import pickle
import importlib
import io
import traceback
import subprocess

class Py3Wrapper(object):
    def __init__(self, mod_name, func_name):
        self.mod_name = mod_name
        self.func_name = func_name

    def __call__(self, *args, **kwargs):
        p = subprocess.Popen(['python3', '-m', 'py3bridge',
                              self.mod_name, self.func_name],
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE)
        stdout, _ = p.communicate(pickle.dumps((args, kwargs)))
        data = pickle.loads(stdout)
        if data['success']:
            return data['result']
        else:
            raise Exception(data['stacktrace'])

def main():
    try:
        target_module = sys.argv[1]
        target_function = sys.argv[2]
        args, kwargs = pickle.load(sys.stdin.buffer)
        mod = importlib.import_module(target_module)
        func = getattr(mod, target_function)
        result = func(*args, **kwargs)
        data = dict(success=True, result=result)
    except Exception:
        st = io.StringIO()
        traceback.print_exc(file=st)
        data = dict(success=False, stacktrace=st.getvalue())

    pickle.dump(data, sys.stdout.buffer, 2)

if __name__ == '__main__':
    main()

Python 3 模块(使用 pathlib 模块进行展示)

# spam.py

import pathlib

def listdir(p):
    return [str(c) for c in pathlib.Path(p).iterdir()]

使用 spam.listdir

的 Python 2 模块
# beans.py

import py3bridge

delegate = py3bridge.Py3Wrapper('spam', 'listdir')
py3result = delegate('.')
print py3result

关于python - 使用不同的 Python 版本调用 Python 函数最接近的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39451822/

相关文章:

c++ - 如何使用 pstreams 获得完整的流输出?

python - 停止等待 popen 的 python 线程?

c - fclose()/pclose() 可能会阻塞某些文件指针

python - 使用 Python 的 scikit-learn 中随机森林算法的置信度与概率

c++ - 我们可以创建一个 VC++ 可执行文件,它可以在 32 位和 64 位 Windows 上本地运行吗?

c++ - 内存布局继承

javascript - 阻止访问基于 Javascript 的网站或

python - 用钢笔在 Canvas 上删除

python - CNN 后跟用于签名验证的 RNN 的训练和测试准确性不会增加

python - 请解释这个 python 循环,它计算为一个数组并被求和()