从 Python 3 调用 Python 2 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27863832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling Python 2 script from Python 3
提问by Gary Ye
I have two scripts, the main is in Python 3, and the second one is written in Python 2 (it also uses a Python 2 library).
我有两个脚本,主要在 Python 3 中,第二个是用 Python 2 编写的(它也使用 Python 2 库)。
There is one method in the Python 2 script I want to call from the Python 3 script, but I don't know how to cross this bridge.
我想从Python 3脚本调用Python 2脚本中的一种方法,但我不知道如何跨过这座桥。
回答by mikelsr
You could run python2 from bash using subprocess (python module) doing the following:
您可以使用子进程(python 模块)从 bash 运行 python2,执行以下操作:
From python 3:
从蟒蛇3:
#!/usr/bin/env python3
import subprocess
python3_command = "py2file.py arg1 arg2" # launch your python2 script using bash
process = subprocess.Popen(python3_command.split(), stdout=subprocess.PIPE)
output, error = process.communicate() # receive output from the python2 script
Where output stores whatever python 2 returned
输出存储python 2返回的任何内容
回答by Frank-Rene Sch?fer
Calling different python versions from each other can be done very elegantly using execnet. The following function does the charm:
使用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()
Example: A my_module.py
written in Python 2.7:
示例:my_module.py
用 Python 2.7 编写的A :
def my_function(X, Y):
return "Hello %s %s!" % (X, Y)
Then the following function calls
然后下面的函数调用
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)
result in
导致
Hello Mr Bear!
Hello Mrs Wolf!
What happened is that a 'gateway' was instantiated waiting
for an argument list with channel.receive()
. Once it came in, it as been translated and passed to my_function
. my_function
returned the string it generated and channel.send(...)
sent the string back. On other side of the gateway channel.receive()
catches that result and returns it to the caller. The caller finally prints the string as produced by my_function
in the python 3 module.
发生的事情是一个“网关”被实例化,等待带有channel.receive()
. 一旦它进来,它就会被翻译并传递给my_function
. my_function
返回它生成的字符串并将channel.send(...)
字符串发回。网关的另一端channel.receive()
捕获该结果并将其返回给调用者。调用者最终打印了my_function
在 python 3 模块中生成的字符串。
回答by excyberlabber
I am running my python code with python 3, but I need a tool (ocropus) that is written with python 2.7. I spent a long time trying all these options with subprocess, and kept having errors, and the script would not complete. From the command line, it runs just fine. So I finally tried something simple that worked, but that I had not found in my searches online. I put the ocropus command inside a bash script:
我正在使用 python 3 运行我的 python 代码,但我需要一个用 python 2.7 编写的工具(ocropus)。我花了很长时间在子进程中尝试所有这些选项,并不断出错,脚本无法完成。从命令行,它运行得很好。所以我终于尝试了一些简单有效的方法,但我在网上搜索中没有找到。我将 ocropus 命令放在一个 bash 脚本中:
#!/bin/bash
/usr/local/bin/ocropus-gpageseg
I call the bash script with subprocess.
我用子进程调用 bash 脚本。
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)
This really gives the ocropus script its own little world, which it seems to need. I am posting this in the hope that it will save someone else some time.
这确实为 ocropus 脚本提供了它自己似乎需要的小世界。我发布此信息是希望它能为其他人节省一些时间。
回答by Fred Jensen
Note: This was happening when running my python 2.x s/w in the liclipse IDE. When I ran it from a bash script on the command line it didn't have the problem. Here is a problem & solution I had when mixing python 2.x & 3.x scripts.
注意:这是在 liclipse IDE 中运行我的 python 2.xs/w 时发生的。当我在命令行上从 bash 脚本运行它时,它没有问题。这是我在混合 python 2.x 和 3.x 脚本时遇到的一个问题和解决方案。
I am running a python 2.6 process & needed to call/execute a python 3.6 script. The environment variable PYTHONPATH was set to point to 2.6 python s/w, so it was choking on the followng:
我正在运行 python 2.6 进程 & 需要调用/执行 python 3.6 脚本。环境变量 PYTHONPATH 被设置为指向 2.6 python s/w,因此它在以下内容中窒息:
File "/usr/lib64/python2.6/encodings/__init__.py", line 123
raise CodecRegistryError,\
This caused the 3.6 python script to fail. So instead of calling the 3.6 program directly I created a bash script which nuked the PYTHONPATH environment variable.
这导致 3.6 python 脚本失败。因此,我没有直接调用 3.6 程序,而是创建了一个 bash 脚本,它破坏了 PYTHONPATH 环境变量。
#!/bin/bash
export PYTHONPATH=
## Now call the 3.6 python scrtipt
./36psrc/rpiapi/RPiAPI.py
回答by sparrow
It works for me if I call the python 2 executable directly from a python 3 environment.
如果我直接从 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()
回答by Martin Koubek
Maybe to late, but there is one more simple option for call python2.7 scripts:
也许为时已晚,但还有一个更简单的调用 python2.7 脚本的选项:
script = ["python2.7", "script.py", "arg1"]
process = subprocess.Popen(" ".join(script),
shell=True,
env={"PYTHONPATH": "."})
回答by Freeman
I recommend to convert the Python2 files to Python3:
我建议将 Python2 文件转换为 Python3: