在python脚本中使用conda install

sla*_*law 16 python installation anaconda conda

根据这个答案,您可以从Python脚本中导入pip并使用它来安装模块.有可能这样做conda install吗?

conda文档仅显示命令行中的示例,但我正在寻找可以在Python脚本中执行的代码.

是的,我可以从脚本中执行shell命令,但我试图避免这种情况,因为它基本上假设无法导入conda并调用其函数.

Mik*_*ler 17

你可以用conda.cli.main.例如,这安装numpy:

import conda.cli

conda.cli.main('conda', 'install',  '-y', 'numpy')
Run Code Online (Sandbox Code Playgroud)

使用-y参数来避免交互式问题:

-y, - 是不要求确认.

  • 我发现当我尝试使用具有命令行参数的脚本执行此操作时,conda 试图解释命令行参数而不是 `conda.cli.main()` 的参数,因此使用 `conda.cli.main( )` 像这样可能不适用于某些事情。 (2认同)
  • @pceccon 只需添加参数`'-c'、'<CHANNEL>'`。以我的回答为例。 (2认同)

ws_*_*421 6

使用condaPython 脚本已经有一段时间了,我认为使用conda模块调用subprocess总体效果最好。在 Python 3.7+ 中,你可以这样做:

import json
from subprocess import run


def conda_list(environment):
    proc = run(["conda", "list", "--json", "--name", environment],
               text=True, capture_output=True)
    return json.loads(proc.stdout)


def conda_install(environment, *package):
    proc = run(["conda", "install", "--quiet", "--name", environment] + packages,
               text=True, capture_output=True)
    return json.loads(proc.stdout)
Run Code Online (Sandbox Code Playgroud)

正如我在评论中指出的那样,conda.cli.main()不适合外部使用。它直接解析sys.argv,因此如果您尝试在自己的脚本中使用自己的命令行参数,它们也会被提供conda.cli.main()

@YenForYang 的答案建议conda.cli.python_api更好,因为这是一个公开记录的用于调用conda命令的 API。然而,我发现它仍然有粗糙的边缘。conda在执行命令时建立内部状态(例如缓存)。conda 通常使用和测试的方式是作为命令行程序。在这种情况下,该内部状态将在命令结束时被丢弃conda。使用conda.cli.python_api,您可以conda在单个进程中执行多个命令。在这种情况下,内部状态会继续存在,有时会导致意外结果(例如,在执行命令时缓存会变得过时)。当然,应该可以conda直接处理这个内部状态。我的观点只是,使用conda这种方式并不是开发人员的主要关注点。如果您想要最可靠的方法,请使用conda开发人员希望使用的方式 - 作为其自己的流程。

conda是一个相当慢的命令,所以我认为人们不应该担心调用子进程对性能的影响。正如我在另一条评论中指出的,pip是一个类似的工具,conda并在其文档中明确指出它应该作为子进程调用,而不是导入到 Python 中


Yen*_*ang 5

I was looking at the latest Conda Python API and noticed that there are actually only 2 public modules with “very long-term stability”:

  1. conda.cli.python_api
  2. conda.api

For your question, I would work with the first:

NOTE: run_command() below will always add a -y/--yes option (i.e. it will not ask for confirmation)

import conda.cli.python_api as Conda
import sys

###################################################################################################
# The below is roughly equivalent to:
#   conda install -y 'args-go-here' 'no-whitespace-splitting-occurs' 'square-brackets-optional'

(stdout_str, stderr_str, return_code_int) = Conda.run_command(
    Conda.Commands.INSTALL, # alternatively, you can just say "install"
                            # ...it's probably safer long-term to use the Commands class though
                            # Commands include:
                            #  CLEAN,CONFIG,CREATE,INFO,INSTALL,HELP,LIST,REMOVE,SEARCH,UPDATE,RUN
    [ 'args-go-here', 'no-whitespace-splitting-occurs', 'square-brackets-optional' ],
    use_exception_handler=True,  # Defaults to False, use that if you want to handle your own exceptions
    stdout=sys.stdout, # Defaults to being returned as a str (stdout_str)
    stderr=sys.stderr, # Also defaults to being returned as str (stderr_str)
    search_path=Conda.SEARCH_PATH  # this is the default; adding only for illustrative purposes
)
###################################################################################################

Run Code Online (Sandbox Code Playgroud)


The nice thing about using the above is that it solves a problem that occurs (mentioned in the comments above) when using conda.cli.main():

...conda tried to interpret the comand line arguments instead of the arguments of conda.cli.main(), so using conda.cli.main() like this might not work for some things.


The other question in the comments above was:

How [to install a package] when the channel is not the default?

import conda.cli.python_api as Conda
import sys

###################################################################################################
# Either:
#   conda install -y -c <CHANNEL> <PACKAGE>
# Or (>= conda 4.6)
#   conda install -y <CHANNEL>::<PACKAGE>

(stdout_str, stderr_str, return_code_int) = Conda.run_command(
    Conda.Commands.INSTALL,
    '-c', '<CHANNEL>',
    '<PACKAGE>'
    use_exception_handler=True, stdout=sys.stdout, stderr=sys.stderr
)
###################################################################################################

Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案。最初接受的答案依赖于内部API,但不能保证稳定性。另外,我认为完整的答案应该提到使用`subprocess`模块调用conda。使用`--json`选项从`subprocess`模块调用conda并解析结果是完全有效的,甚至可能更加稳定。它也不需要在conda环境中安装`conda`。由于性能原因避免使用“ subprocess”可能是过早的优化。 (2认同)