在 Python 3.2 中调用一个 Python 2.7 模块
Call a Python 2.7 module in Python 3.2
我有一个 GUI 程序,是我在 Python 3.2 中开发的,用于提取各种地理空间数据产品。我需要调用我在 Python 2.7 中开发的模块。
我正在寻找一种能够在 Python 3.2 程序中使用 Python 2.7 解释器调用 Python 2.7 代码的方法。我无法将 2.7 移植到 Python 3.2,因为它使用随 ESRI ArcMap 安装的 Python 版本,并且依赖于 Python 3 不可用的 arcpy 模块。我现在唯一的想法是是使用 subprocess 将模块作为批处理调用,但这有点混乱,我希望这两个程序有一些关系。
提前致谢。
尝试使用 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
您可以在 3.2 上生成 python 2.7 进程作为处理来自 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
.
来使其相当透明
现在的诀窍是确保您的所有参数都可以序列化,并且您可以在每次调用的合理时间内实际发送所有 arguments/return 值。此外,您失去了更改传递给包装器的变量内容的能力,因为服务器将仅修改本地副本(除非您也实现对所有这些修改的序列化)
有点晚了,但万一有人偶然发现了这个话题:
我写了一个 module 可以在其他 python 解释器中透明地运行部分程序。基本上它提供了装饰器和基础类,用与其他解释器交互的代理替换函数和对象。
这是为了兼容性,例如运行 python2
仅在 python3
中编写代码,或从 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)
我有一个 GUI 程序,是我在 Python 3.2 中开发的,用于提取各种地理空间数据产品。我需要调用我在 Python 2.7 中开发的模块。
我正在寻找一种能够在 Python 3.2 程序中使用 Python 2.7 解释器调用 Python 2.7 代码的方法。我无法将 2.7 移植到 Python 3.2,因为它使用随 ESRI ArcMap 安装的 Python 版本,并且依赖于 Python 3 不可用的 arcpy 模块。我现在唯一的想法是是使用 subprocess 将模块作为批处理调用,但这有点混乱,我希望这两个程序有一些关系。
提前致谢。
尝试使用 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
您可以在 3.2 上生成 python 2.7 进程作为处理来自 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
.
现在的诀窍是确保您的所有参数都可以序列化,并且您可以在每次调用的合理时间内实际发送所有 arguments/return 值。此外,您失去了更改传递给包装器的变量内容的能力,因为服务器将仅修改本地副本(除非您也实现对所有这些修改的序列化)
有点晚了,但万一有人偶然发现了这个话题:
我写了一个 module 可以在其他 python 解释器中透明地运行部分程序。基本上它提供了装饰器和基础类,用与其他解释器交互的代理替换函数和对象。
这是为了兼容性,例如运行 python2
仅在 python3
中编写代码,或从 pypy
.
在下面的示例中,使用 pypy
的循环运行速度是使用普通 python
.
#!/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)