在Anaconda环境下使用subprocess

10

我使用的Python版本是3.6.6 :: Anaconda, Inc.

我尝试使用subprocess来调用其他的Python脚本。

subprocess.run("python -V", shell=True)

我尝试了这段代码,但结果是:

Python 2.7.12

我的本地Python被卡住了。

我还尝试了其他方法。

subprocess.run("bash -c 'source /home/hclee/anaconda3/envs/calamari/lib/python3.6/venv/scripts/common/activate
/home/hclee/anaconda3/envs/calamari && python -V && source deactivate'", shell=True)

但我得到了相同的结果


1
你的默认 Python 别名设置为系统 Python,即 Python 2.7.12。如果你想将默认的 python 更改为 3.6.6,你需要更改 Python 别名。 - user2906838
Anaconda默认安装了Python 2.7.12,但也包括Python 3.6.6。如果您想选择Python 3,则可以创建一个环境,例如conda create -n myenv python=3.6,然后需要“激活”该环境才能使用它。输入conda activate myenv即可。 然后,如果您执行python -V,应该会得到Python 3.6.6。 完成后,您可以使用conda deactivate退出环境。 - jalazbe
你能发布 envsubprocess.run("env") 的输出吗? - Nils Werner
1
@jalazbe 这个说法不正确。这取决于您安装的Anaconda版本。正如您可以在这里看到的,有一个默认python3版本的下载和一个默认python2版本的不同下载。 - FlyingTeller
@FlyingTeller 感谢您提供的信息。您是正确的。这取决于所选择的安装包。 - jalazbe
@NilsWerner 我的 subprocess.run("env") 输出为 PYTHONPATH=/home/hclee/calamari PYTHONIOENCODING=UTF-8。 - hochan
4个回答

11

在Linux中运行source activate root,或者在Windows中运行activate root以激活环境,在运行代码之前。

如果这不能帮到你,请尝试快速而肮脏的解决方案,例如:

subprocess.run('bash -c "source activate root; python -V"', shell=True)

之所以需要调用bash是因为Python的run函数不会调用bash环境,而是调用了另一个更加受限制且不含有source命令的环境,所以我们需要调用bash。但正如提到的,如果您需要这个命令,要么您正在做一些特殊的事情,要么您的环境出现了问题...

deactivate没有必要,因为它无法执行任何操作,因为运行它的shell将被销毁...

注意:对于最新的conda版本,提供的代码将起作用,但也有类似的选项:

conda deactivate

subprocess.run('bash -c "conda deactivate; python -V"', shell=True)

conda activate rootbase

subprocess.run('bash -c "conda activate root; python -V"', shell=True)
subprocess.run('bash -c "conda activate base; python -V"', shell=True)

我正在运行Linux Mint(Ubuntu),所以只能对它进行评论,但是我刚刚尝试运行它并接受了“root”,但没有识别“base”。此外,我无法执行conda激活操作:https://i.stack.imgur.com/CK4UN.png - ntg
1
你使用的conda版本是多少?@jalazbe提到的更改发生在conda 4.4中。 - darthbith
它在我的终端上可以运行,但是在我的PyCharm中无法工作。我导入的其他模块来自我的Anaconda环境。但是子进程来自“/pycharm-community-2018.1.4/helpers/typeshed/stdlib/3”。我不知道这里发生了什么。 - hochan
@darthbith,我的conda版本是4.5.4。 - hochan
@hochan:你在PyCharm中设置了正确的解释器吗?https://dev59.com/-WIk5IYBdhLWcg3wAJ2E - ntg
显示剩余6条评论

4

我认为在代码的每个subprocess调用中都引用一个conda环境并不是一个好主意。

相反,您可以找到当前引用环境的bin目录,并从那里获取二进制文件的完整路径。然后在需要调用它们时将这些路径传递给subprocess

import os
import sys
import subprocess

# what conda env am I in (e.g., where is my Python process from)?
ENVBIN = sys.exec_prefix

# what binaries am I looking for that are installed in this env?
BIN1 = os.path.join(ENVBIN, "bin", "ipython")
BIN2 = os.path.join(ENVBIN, "bin", "python")
BIN3 = os.path.join(ENVBIN, "bin", "aws")

# let's make sure they exist, no typos.
for bin in (BIN1, BIN2, BIN3):
    assert os.path.exists(bin), "missing binary {} in env {}".format(bin, ENVBIN)

# then use their full paths when making subprocess calls
for bin in (BIN1, BIN2, BIN3):
    cmd = ["which", bin]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    print(proc.communicate()[0].decode())

打印的结果表明 subprocess 正在使用 conda 环境中的二进制文件,而不是基础(默认)环境中的二进制文件。
.../miniconda3/envs/aws/bin/ipython
.../miniconda3/envs/aws/bin/python
.../miniconda3/envs/aws/bin/aws

2
这通常可以正常工作,但如果环境中包含具有自定义激活代码的软件包,则可能会出现错误。 - Christopher Barber

0
如果您的控制台/笔记本已经使用了正确的环境,您可以使用sys.executable调用subprocess来使用当前环境:
import sys
import subprocess
subprocess.run(f"{sys.executable} -V", shell=True)

sys.executable 只会给出当前 Jupyter 运行的文件夹,而不是在 https://dev59.com/BloV5IYBdhLWcg3wN8nh 中描述的 env_path。 - MosQuan
@MosQuan sys.executable 返回当前环境中 python.exe 的完整路径,因此您可以确保使用正确的版本调用 python。在您提供的示例中,他们拆分了 sys.executable 以获取文件夹。 - ronkov

0
以上的解决方案对我没有用。 真正起作用的是:
import subprocess
output = subprocess.run('''python -c "import sys; print(sys.executable)"
                  source <your-conda-base-dir>/etc/profile.d/conda.sh
                  conda activate <name-of-the-conda-environment-you-want-to-activate>
                  python -c "import sys; print(sys.executable)"
                  conda env export''', executable='/bin/bash', shell=True, capture_output=True)
print(bytes.decode(output.stdout))

<your-conda-base-dir>替换为在通常用于执行conda命令的交互式终端中执行which conda的输出,但从您获得的输出末尾删除/condabin/conda,以便在执行上述subprocess.run()时找到/etc/profile.d/conda.sh位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接