在代码中安装python模块

我需要在我的脚本中直接从PyPi安装一个包。 也许有一些模块或distutils (distributepip等)特性,允许我只执行类似pypi.install('requests')的东西,请求将被安装到我的virtualenv

455716 次浏览

你可以用"install_requires"选项在你自己的包的setup.py中定义依赖模块。

如果你的包需要生成一些控制台脚本,那么你可以使用“console_scripts”入口点来生成一个包装器脚本

.在'bin'文件夹中(例如你的virtualenv环境)

这应该可以工作:

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。

使用sys.executable来确保调用与当前运行时相关联的相同pip

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文件,其中包含以下代码:

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检查是否已经满足了要求。

这适用于不同的要求说明符,这很好。例如:>===

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)

demo

相关信息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])