我需要在我的脚本中直接从PyPi安装一个包。 也许有一些模块或distutils (distribute, pip等)特性,允许我只执行类似pypi.install('requests')的东西,请求将被安装到我的virtualenv
distutils
distribute
pip
pypi.install('requests')
你可以用"install_requires"选项在你自己的包的setup.py中定义依赖模块。
这应该可以工作:
import subprocess def install(name): subprocess.call(['pip', 'install', name])
你还可以使用如下语句:
import pip def install(package): if hasattr(pip, 'main'): pip.main(['install', package]) else: pip._internal.main(['install', package]) # Example if __name__ == '__main__': install('argh')
如果你想使用pip来安装所需的包,并在安装后导入它,你可以使用下面的代码:
def install_and_import(package): import importlib try: importlib.import_module(package) except ImportError: import pip pip.main(['install', package]) finally: globals()[package] = importlib.import_module(package) install_and_import('transliterate')
如果您以用户身份安装包,可能会遇到不能直接导入包的问题。更多信息请参见如何刷新sys.path?。
官方推荐的从脚本安装包的方法是通过子进程调用pip的命令行接口。这里提供的大多数其他答案都不支持pip。此外,从pip v10开始,所有的代码都被移动到pip._internal,正是为了让用户清楚地知道,不允许以编程方式使用pip。
pip._internal
使用sys.executable来确保调用与当前运行时相关联的相同pip。
sys.executable
import subprocess import sys def install(package): subprocess.check_call([sys.executable, "-m", "pip", "install", package])
我在@Aaron的回答中添加了一些异常处理。
import subprocess import sys try: import pandas as pd except ImportError: subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas']) finally: import pandas as pd
为了安装多个包,我使用了setup.py文件,其中包含以下代码:
setup.py
import sys import subprocess import pkg_resources required = {'numpy', 'pandas', '<etc>'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed if missing: # implement pip as a subprocess: subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])
import os os.system('pip install requests')
我尝试了上述临时解决方案,而不是更改docker文件。希望这些可能对一些人有用
试试下面的。到目前为止,对我来说是最好的 首先安装4个,然后在REQUIRED列表中提到新的
import pkg_resources import subprocess import sys import os REQUIRED = { 'spacy', 'scikit-learn', 'numpy', 'pandas', 'torch', 'pyfunctional', 'textblob', 'seaborn', 'matplotlib' } installed = {pkg.key for pkg in pkg_resources.working_set} missing = REQUIRED - installed if missing: python = sys.executable subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
如果你想要一个更有效的答案,扩展subprocess.check_call。您可以首先使用pkg_resources检查是否已经满足了要求。
subprocess.check_call
pkg_resources
这适用于不同的要求说明符,这很好。例如:>=, ==
>=
==
import sys import subprocess import pkg_resources from pkg_resources import DistributionNotFound, VersionConflict def should_install_requirement(requirement): should_install = False try: pkg_resources.require(requirement) except (DistributionNotFound, VersionConflict): should_install = True return should_install def install_packages(requirement_list): try: requirements = [ requirement for requirement in requirement_list if should_install_requirement(requirement) ] if len(requirements) > 0: subprocess.check_call([sys.executable, "-m", "pip", "install", *requirements]) else: print("Requirements already satisfied.") except Exception as e: print(e)
使用示例:
requirement_list = ['requests', 'httpx==0.18.2'] install_packages(requirement_list)
相关信息Stackoverflow问题:58612272
为了有条件地用准确的版本安装多个包,我一直在使用基于@Tanmay Shrivastava回答的这个模式:
import sys from subprocess import run, PIPE, STDOUT import pkg_resources def run_cmd(cmd): ps = run(cmd, stdout=PIPE, stderr=STDOUT, shell=True, text=True) print(ps.stdout) # packages to be conditionally installed with exact version required = {"click==8.0.1", "semver==3.0.0.dev2"} installed = {f"{pkg.key}=={pkg.version}" for pkg in pkg_resources.working_set} missing = required - installed if missing: run_cmd(f'pip install --ignore-installed {" ".join([*missing])}')
import pip try: import imaplib import email import pandas as pd # for hiding password from pathlib import Path from dotenv import load_dotenv import os import requests # from collections import defaultdict from itertools import permutations,combinations except Exception as e: print(e) e = str(e).split(' ')[-1].replace("'","") pip.main(['install', e])