我有两个脚本,主要的是用Python 3编写的,第二个是用Python 2编写的(它也使用了一个Python 2库)。
Python 2脚本中有一个方法,我想从Python 3脚本中调用,但我不知道如何跨越这个鸿沟。
我有两个脚本,主要的是用Python 3编写的,第二个是用Python 2编写的(它也使用了一个Python 2库)。
Python 2脚本中有一个方法,我想从Python 3脚本中调用,但我不知道如何跨越这个鸿沟。
使用execnet非常优雅地调用不同版本的Python。下面的函数可以实现此功能:
import execnet
def call_python_version(Version, Module, Function, ArgumentList):
gw = execnet.makegateway("popen//python=python%s" % Version)
channel = gw.remote_exec("""
from %s import %s as the_function
channel.send(the_function(*channel.receive()))
""" % (Module, Function))
channel.send(ArgumentList)
return channel.receive()
示例:一个用Python 2.7编写的my_module.py
:
def my_function(X, Y):
return "Hello %s %s!" % (X, Y)
接下来是以下函数调用:
result = call_python_version("2.7", "my_module", "my_function",
["Mr", "Bear"])
print(result)
result = call_python_version("2.7", "my_module", "my_function",
["Mrs", "Wolf"])
print(result)
导致
Hello Mr Bear!
Hello Mrs Wolf!
channel.receive()
参数列表的到来。一旦它到达,它就被翻译并传递给my_function
。 my_function
返回它生成的字符串,channel.send(...)
将字符串发送回去。在网关的另一侧,channel.receive()
捕获结果并将其返回给调用者。调用者最终在Python 3模块中打印由my_function
生成的字符串。execnet
目前处于维护模式,主要是因为它仍然是 pytest-xdist
插件的后端。不要在新项目中使用。” 嗯,现在该怎么办? - ijoseph您可以使用 subprocess(Python 模块)运行 Python2,方法如下:
从 Python 3 开始:
#!/usr/bin/env python3
import subprocess
python3_command = "py2file.py arg1 arg2" # launch your python2 script
process = subprocess.Popen(python3_command.split(), stdout=subprocess.PIPE)
output, error = process.communicate() # receive output from the python2 script
输出存储Python 2返回的任何内容
subprocess.call
。https://dev59.com/SnVD5IYBdhLWcg3wGXlI#89243 - Matt KleinsmithOSError: [Errno 2] No such file or directory
(我正在尝试从Py 2启动Py 3;示例目标脚本只有1个打印语句)。此外,我非常困惑这是否像frakman1所说的那样工作,还是像@MatthewLueder暗示的那样没有工作? - Hack-Rscript = ["python2.7", "script.py", "arg1"]
process = subprocess.Popen(" ".join(script),
shell=True,
env={"PYTHONPATH": "."})
我正在使用Python 3运行我的代码,但我需要一个用Python 2.7编写的工具(ocropus)。我尝试了很长时间的subprocess选项,但一直出现错误,脚本无法完成。从命令行可以正常运行。最后我尝试了一些简单的方法,这些方法有效,但我在网上搜索时没有找到。我将ocropus命令放在一个bash脚本中:
#!/bin/bash
/usr/local/bin/ocropus-gpageseg $1
command = [ocropus_gpageseg_path, current_path]
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output, error = process.communicate()
print('output',output,'error',error)
这确实给了ocropus脚本一个独立的小世界,它似乎需要这样。我发布这篇文章,希望能为其他人节省一些时间。
如果我直接从Python 3环境中调用Python 2可执行文件,那么它对我有效。
python2_command = 'C:\Python27\python.exe python2_script.py arg1'
process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
python3_command = 'python python3_script.py arg1'
process = subprocess.Popen(python3_command.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
run()
,如subprocess docs所推荐。def foo27(input):
return input * 2
import ast
import subprocess
def foo3(parameter):
try:
return ast.literal_eval(subprocess.run(
[
"C:/path/to/python2.7/python.exe", "-c", # run python2.7 in command mode
"from bar import foo27;"+
"print(foo27({}))".format(parameter) # print the output
],
capture_output=True,
check=True
).stdout.decode("utf-8")) # evaluate the printed output
except subprocess.CalledProcessError as e:
print(e.stdout)
raise Exception("foo27 errored with message below:\n\n{}"
.format(e.stderr.decode("utf-8")))
print(foo3(21))
# 42
File "/usr/lib64/python2.6/encodings/__init__.py", line 123
raise CodecRegistryError,\
这导致了3.6版本的Python脚本失败。 因此,我没有直接调用3.6程序,而是创建了一个Bash脚本来清除PYTHONPATH环境变量。
#!/bin/bash
export PYTHONPATH=
## Now call the 3.6 python scrtipt
./36psrc/rpiapi/RPiAPI.py $1
如果你不想在Python 3中调用它们,可以通过创建批处理文件在conda env批处理中运行它们,如下所示:
call C:\ProgramData\AnacondaNew\Scripts\activate.bat
C:\Python27\python.exe "script27.py" C:\ProgramData\AnacondaNew\python.exe "script3.py"
call conda deactivate
pause
我建议将Python2文件转换为Python3: