我在 git 问题跟踪器上发布了这个问题:https://github.com/pypa/pip/issues/2969
我们能否以某种方式在 python 中调用 pip freeze/list,即不是 shell 上下文?
我希望能够导入 pip 并执行类似 requests = pip.freeze() 的操作。调用 pip.main(['freeze']) 写入标准输出,不返回 str 值。
较新版本 (>1.x) 中有 pip.operation.freeze:
try: from pip._internal.operations import freeze
except ImportError: # pip < 10.0
from pip.operations import freeze
pkgs = freeze.freeze()
for pkg in pkgs: print(pkg)
输出如预期:
amqp==1.4.6
任何json==0.3.3
台球==3.3.0.20
defusedxml==0.4.1
姜戈==1.8.1
django-picklefield==0.3.1
文档==0.12
...等等
pip不支持这里的其他答案:https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program
根据 pip 开发者的说法:
如果您直接导入 pip 的内部结构并使用它们,则这不是受支持的用例。
尝试
reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
不建议依赖“私有”函数,例如
pip._internal.operatons
。您可以执行以下操作:
import pkg_resources
env = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set)
pip >= 10.0.0
包 operations.freeze
已移至 pip._internal.operations.freeze
。
所以安全的导入方式
freeze
是:
try:
from pip._internal.operations import freeze
except ImportError:
from pip.operations import freeze
为了构建上面 sedeh 和 Marvin 的答案,我找到了一个 as_requirements() 方法,所以这对我来说几乎相当于 pip freeze。
excluded_packages = ['wheel', 'setuptools', 'pip']
modules = [str(p.as_requirement()) for p in pkg_resources.working_set if p and p.key not in excluded_packages]
我遇到的唯一问题是“打字扩展”与“打字扩展”。两者似乎都是 pip install 所以似乎不是一个大问题。
由于不建议依赖诸如
pip._internal.operatons
之类的私有函数,并且建议作为替代方案的 pkg_resources
现已弃用,因此我建议使用 importlib.metadata
代替。
from importlib import metadata
dists = metadata.distributions()
for dist in dists:
name = dist.metadata["Name"]
version = dist.version
print(name, version)