pythonw子进程无法调用另一个版本的python

时间:2018-02-27 18:03:53

标签: python subprocess miniconda pythonw

在开始之前,我的环境有一些注意事项:通过miniconda安装的python 2.7.14,macOS 10.13.3。

问题

我正在尝试在python中编写一个数据处理管道(称为analyze.py),它调用了几个不同的程序。其中一个程序EMAN2使用自己的python环境运行(位于,~/EMAN2/bin/python)。从命令行,对eman2的调用可能如下所示:

~/EMAN2/bin/e2buildstacks.py <args>

其中e2buildstacks.py使用文件顶部的标准#!/Users/<username>/EMAN2/bin/python类型公式指定其自己的python环境(注意,有很多这些不同的.py文件要运行,我只是使用一个名字作为例子。)

在python中,我正在为这些调用使用subprocess.Popen构造。一个非常简单的例子是:

import subprocess
stacks_cmd = '/Users/<username>/EMAN2/bin/e2buildstacks.py <args>'
process = subprocess.Popen(stacks_cmd, shell=True, stdout=subprocess.PIPE)
stacks_output, stacks_error = process.communicate()

为了简单起见,我已经替换了实际的args和用户名。

如果这就是我正在做的事情,它运作正常。我可以从命令行运行python analyze.py,它可以毫无问题地运行EMAN2。

然而,这个管道正在包含在GUI(基于wxpython)中。所以我必须使用pythonw来运行我的程序。当我尝试做的时候:

pythonw analyze.py

它无法正确运行EMAN2脚本,我收到错误:

Traceback (most recent call last):
  File "/Users/<username>/EMAN2/bin/e2buildstacks.py", line 34, in <module>
    from EMAN2 import *
ImportError: No module named EMAN2

这向我表明它正在使用我的miniconda python而不是~/EMAN2/bin/python来运行脚本。

(注意:如果有人使用EMAN2,我可以为您提供完整的参数列表和输入文件。但请放心,这不是问题,我可以在命令行运行命令我正常使用)< / p>

我尝试了什么

我尝试了几种不同的方法来解决这个问题。最简单的是指定在命令中使用的python:

import subprocess
stacks_cmd = '/Users/<username>/EMAN2/bin/python /Users/<username>/EMAN2/bin/e2buildstacks.py <args>'
process = subprocess.Popen(stacks_cmd, shell=True, stdout=subprocess.PIPE)
stacks_output, stacks_error = process.communicate()

这不起作用,并以相同的错误失败。

我尝试在shell = False模式下使用Popen

import subprocess
stacks_cmd = ['/Users/<username>/EMAN2/bin/python', '/Users/<username>/EMAN2/bin/e2buildstacks.py', <args>]
process = subprocess.Popen(stacks_cmd, shell=False, stdout=subprocess.PIPE)
stacks_output, stacks_error = process.communicate()

import subprocess
stacks_cmd = ['/Users/<username>/EMAN2/bin/e2buildstacks.py', <args>]
process = subprocess.Popen(stacks_cmd, shell=False, stdout=subprocess.PIPE)
stacks_output, stacks_error = process.communicate()

两者都失败并出现同样的错误。

我已尝试指定可执行文件:

import subprocess
stacks_cmd = ['/Users/<username>/EMAN2/bin/e2buildstacks.py', <args>]
process = subprocess.Popen(stacks_cmd, shell=False, stdout=subprocess.PIPE, executable='/Users/<username>/EMAN2/bin/python')
stacks_output, stacks_error = process.communicate()

这个给出了不同的错误:

Unknown option: --
usage: /Users/<username>/EMAN2/bin/e2buildstacks.py [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.

这让我觉得参数不会正确地传递给脚本,而是传递给python本身(我可能不太明白这里的可执行设置是什么)。

我尝试过设置环境变量:

import os
my_env = os.environ.copy()
my_env['PATH'] = '/Users/<username>/EMAN2/bin:'+my_env['PATH']
my_env['PYTHONPATH'] = '/Users/<username>/EMAN2/bin'

然后将其传递给上述任何命令中的subprocess.Popen env=my_env。这失败并出现相同的错误。

此时,我几乎没有想法,希望有人可以提供帮助。同样,这只发生在pythonw,而不是python

我读过的东西正在寻找解决方案

我在stackoverflow上找不到任何与此问题相匹配的内容。我看过的东西:

subprocess a program using another version of python

  • 从未成功回答。

Module cannot be found when using "pythonw" (instead of "python") to run an application

  • 问题不在于我使用的是哪个python / pythonw,都来自miniconda。

Python subprocess is running a different version of Python

  • 这与我的问题完全相反,因此使用不多。

https://github.com/ContinuumIO/anaconda-issues/issues/199

  • 这表明miniconda pythonw可能会导致各种问题,但不能直接提供解决方案(假设强烈建议不要使用其他版本的python)。

Python subprocess/Popen with a modified environment

Python Script not running in crontab calling pysaunter

  • 这些导致我尝试修改环境变量。

最后的注释

  • 更改正在使用的python发行版是可能的,但非常不是理想的解决方案。我正在写一些将在几个不同的环境中运行的东西(包括我还没有测试过的linux和windows)以及那些不是我的人,所以我需要一个更加防弹的解决方案。

非常感谢任何帮助人员提供的帮助。

0 个答案:

没有答案