pythonw子进程无法调用python的其他版本

2024-05-19 07:08:20 发布

您现在位置:Python中文网/ 问答频道 /正文

在开始之前,请注意我的环境:通过miniconda、macos10.13.3安装的python2.7.14。在

问题

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

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

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

在python中,我使用子流程.Popen这些电话的建设。一个非常简单的例子是:

^{pr2}$

为了简单起见,我替换了实际的参数和用户名。在

如果这就是我所做的一切,那就很好了。我可以从命令行运行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,我可以为您提供完整的参数列表和输入文件。但请放心,这不是问题所在,我可以从命令行运行我正在使用的命令)

我尝试过的

我尝试了几种不同的方法来解决这个问题。最简单的方法是指定要在命令中使用的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'

然后把它传给子流程.Popen在上面的任何命令中,env=my_env。这将失败,并出现相同的错误。在

在这一点上,我几乎没有想法,希望有人能帮忙。同样,这只发生在pythonw,而不是{}。在

我读过的寻找解决方案的文章

我在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,我还没有在这些环境下进行测试),而且我需要一个更安全的解决方案。在

任何人能提供的帮助都是非常感谢的。在


Tags: pyimportenvcmdbinusernameargsprocess

热门问题