【问题标题】:Call a Python 2.7 module in Python 3.2在 Python 3.2 中调用 Python 2.7 模块
【发布时间】:2016-09-16 01:58:49
【问题描述】:

我有一个使用 Python 3.2 开发的 GUI 程序,用于提取各种地理空间数据产品。我需要调用我在 Python 2.7 中开发的模块。

我正在寻找一种能够在 Python 3.2 程序中使用 Python 2.7 解释器调用 Python 2.7 代码的方法。我无法将 2.7 移植到 Python 3.2,因为它使用与 ESRI ArcMap 一起安装的 Python 版本并依赖于 Python 3 不可用的 arcpy 模块。我现在唯一的想法是使用 subprocess 将模块作为批处理调用但是这有点混乱,我希望这两个程序有一些关系。

提前谢谢你。

【问题讨论】:

    标签: python python-2.7 python-3.x subprocess arcpy


    【解决方案1】:

    您可以将 python 2.7 进程作为服务器处理来自 3.2 上运行的 GUI 的 RPC 请求。这将通过网络、本地管道、共享内存、系统的消息总线或许多其他方式工作。您只需要将库的 API 转换为某种序列化消息。

    假设你的库有一个函数:(超级简化示例)

    def add(a, b):
        return a+b
    

    您可以将它封装在某个服务器中,比如flask app,它可以:

    @app.route("/add", methods=["POST"])
    def handle_add():
        data = request.get_json()
        ret = your_lib.add(data['a'], data['b'])
        return jsonify(ret)
    

    在客户端,使用 requests 之类的方式发送和解压值

    您甚至可以通过使用与库本身名称相同的方法实现翻译器模块并执行import your_http_wrapper as your_library_name 来使其相当透明。

    现在的诀窍是确保您的所有参数都可以序列化,并且您可以在每次调用的合理时间内实际发送所有参数/返回值。此外,您将无法更改传递给包装器的变量内容,因为服务器只会修改本地副本(除非您也实现了对所有这些修改的序列化)

    【讨论】:

      【解决方案2】:

      尝试使用subprocess.check_output(['C:\\python27\\python.exe', 'yourModule.py'])

      如果要调用 27 文件中的特定函数,可以使用更多系统参数。调用看起来像:

      subprocess.check_output(['C:\\python27\\python.exe', 'yourModule.py', 'funcName'])
      

      并且在27号文件中可以添加:

      import sys
      if __name__=='__main__':
          if 'funcName' in sys.argv:
              funcName()
           else:
              #... execute normally
      

      【讨论】:

      • 你知道我可以用参数调用这个 python 文件的特定函数吗?
      • 虽然我最初从未打算使用子流程,但这确实可以按预期完成工作,谢谢 :)
      【解决方案3】:

      有点晚了,但万一有人偶然发现这个帖子:

      我写了一个module,它在其他python解释器中透明地运行程序的一部分。基本上,它提供装饰器和基类,用与其他解释器接口的代理替换函数和对象。

      它的目的是为了兼容性,例如仅在python3 中运行python2 代码,或从pypy 访问C 模块。

      在以下示例中,使用 pypy 的循环运行速度是使用普通 python 的 4 倍。

      #!/usr/local/bin/python
      from cpy2py import TwinMaster, twinfunction
      import sys
      import time
      import math
      
      
      # loops in PyPy
      @twinfunction('pypy')
      def prime_sieve(max_val):
          start_time = time.time()
          primes = [1] * 2 + [0] * (max_val - 1)
          for value, factors in enumerate(primes):
              if factors == 0:
                  for multiple in xrange(value*value, max_val + 1, value):
                      primes[multiple] += 1
          return {'xy': [
              [primes[idx] == 0 for idx in range(minidx, minidx + int(math.sqrt(max_val)))]
              for minidx in range(0, max_val, int(math.sqrt(max_val)))
              ], 'info': '%s in %.1fs' % (sys.executable, time.time() - start_time)}
      
      
      # matplotlib in CPython
      @twinfunction('python')
      def draw(xy, info='<None>'):
          from matplotlib import pyplot
          pyplot.copper()
          pyplot.matshow(xy)
          pyplot.xlabel(info, color="red")
          pyplot.show()
      
      if __name__ == '__main__':
          twins = [TwinMaster('python'), TwinMaster('pypy')]
          for twin in twins:
              twin.start()
          data = prime_sieve(int(1E6))
          draw(**data)
      

      【讨论】:

      • 尚未使用,但它看起来非常有用,谢谢!
      猜你喜欢
      • 2012-01-13
      • 1970-01-01
      • 2015-06-15
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2013-04-11
      相关资源
      最近更新 更多