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


当前回答

    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])

其他回答

如果你想要一个更有效的答案,扩展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])}')

我在@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

如果你想使用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?获取更多信息。

    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])