假设我在2种不同的虚拟环境中安装了2个不同版本的应用程序。 myapp v1.0和myapp v2.0。
现在我想比较一下。比较是用python本身编写的。最好的方法是什么?我们假设我可以单独运行它们并且都写一个输出文件,我可以稍后比较。
这样做的一种方法是编写一个bash脚本(这就是我目前所拥有的)。我激活一个virtualenv,运行myapp v1.0,激活另一个virtualenv,运行myapp v2.0。稍后在这些文件上运行比较模块。但是我想在那里添加更多的动态(采用一些可选的参数等),使用python会更容易。
编辑:
目前我有类似的东西(bash脚本):
source virtualenv1/bin/activate
python my_script.py
deactivate
source virtualenv2/bin/activate
python my_other_script.py
deactivate
python my_comparison_script.py
相反,我只想做:
python my_comparison_script.py
我的脚本将在此内部运行。
答案 0 :(得分:33)
接受的答案并没有解决“激活”的问题。子流程中的虚拟现实。
如果通过调用python可执行文件启动应用程序,就像在您的示例中一样,它实际上非常简单:您只需要明确指向virtualenv中的可执行文件。
import subprocess
subprocess.Popen(["virtualenv1/bin/python", "my_script.py"])
subprocess.Popen(["virtualenv2/bin/python", "my_other_script.py"])
将在相应的virtualenvs中启动流程。
重要强>
解决评论中提出的问题:
如果您想运行子流程并确保使用当前流程正在运行的相同的解释器,则必须使用sys.executable。也可用:sys.exec_prefix访问特定于站点的目录前缀,其中安装了与平台相关的Python文件。
如果您想更深入地讨论此主题,请查看此pull request。
答案 1 :(得分:1)
一个简单的选择是如下运行带有子进程的一系列命令。
import subprocess
subprocess.call('source activate my_virtualenv; python my_script.py', shell=True)
并根据需要重复。
答案 2 :(得分:1)
我认为 virtualenv 文档对此进行了很好的解释。
TL; DR
Runnig python venv二进制直接不与激活venv相同。 您还必须相应地更改 PATH 和 VIRTUAL_ENV 变量(请查看os.environ)
$ source / path / to / ENV / bin / activate
这将更改您的$ PATH,因此其第一项是virtualenv的 bin /目录。 (您必须使用source,因为它会更改您的shell 就地环境。)这就是它的全部;纯粹是方便。
如果您直接从中运行脚本或python解释器 virtualenv的bin /目录(例如path / to / ENV / bin / pip或 /path/to/ENV/bin/python-script.py),则sys.path将自动为 设置为使用与virtualenv关联的Python库。但, 与激活脚本不同,环境变量PATH和 VIRTUAL_ENV将不会被修改。这意味着如果您的Python 脚本使用例如子流程来运行另一个Python脚本(例如,通过 !/ usr / bin / env python shebang行),第二个脚本可能无法使用与第一个相同的Python二进制文件执行,也可能没有相同的Python二进制文件 可用的库。为了避免这种情况发生,您的第一个脚本 将需要以与以下相同的方式修改环境变量 激活脚本,然后执行第二个脚本。
答案 3 :(得分:-2)
究竟是什么问题?如何使用子进程执行shell命令?如果是这种情况,一些简单的伪代码可能看起来像:
import subprocess
myProcess = subprocess.Popen( ['these', 'are', 'for', 'the', 'shell'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
[outStream, errStream] = myProcess.communicate()
然后你可以用标准输出(outStream
)做任何你喜欢的事情,并且如果存在errStream
则做不同的事情(标准错误)。这包括将标准输出或标准错误写入文件。然后我猜你会把这些文件区分开来?
一个实际的代码示例(假设你在linux系统上有python 2.6+)可能看起来像:
import subprocess
with open('dateHelp.log', 'w') as dateLog:
with open('dateHelp.err', 'w') as errLog:
dateHelp = subprocess.Popen([ 'date', '-h'], stdout=dateLog,
stderr=errLog)
dateHelp.communicate()