Я пишу небольшой код, который будет сообщать и согласовывать различия между двумя установками Python, управляемыми pip.
Как программно получить информацию, предоставленную pip list
без вызова подпрограммы из пипса?
Я пишу небольшой код, который будет сообщать и согласовывать различия между двумя установками Python, управляемыми pip.
Как программно получить информацию, предоставленную pip list
без вызова подпрограммы из пипса?
Лучшие ответы на 01.02.2009 устарели и больше не работают с более новыми версиями pip.
Но не стоит беспокоиться - все равно можно получить список пакетов программно:
A. _internal.main
from pip import _internal
_internal.main(['list'])
Это распечатает три столбца с пакетом. Версия и местоположение
Обратите внимание, что использование pip внутреннего API не рекомендуется.
A. pkg_resources
import pkg_resources
print([p.project_name for p in pkg_resources.working_set])
# note that this is same as calling pip._vendor.pkg_resources.working_set
B. iter_modules
Требуется много времени для выполнения (~ 300 мс на компьютере с процессором I5, SSD и 8 гигабайтами оперативной памяти). Преимущество состоит в том, что у него будет гораздо более обширный список модулей, и он будет выводить импортируемые имена.
Пример: python-dateutil импортируется как dateutil, но iter_modules даст вам импортируемое имя: dateutil
from pkgutil import iter_modules
print([p.name for p in iter_modules()])
C. Вызовите pip в командной строке через подпроцесс
Решение этого тривиально, и я оставлю это в качестве упражнения для читателя
ака мне лень это делать, удачи! : D
Обновление для Python 3.6 и Pip 19.0.1
> from pip._internal.utils.misc import get_installed_distributions
> p = get_installed_distributions()
> pprint.pprint(p)
[wheel 0.32.3 (/usr/local/lib/python3.7/site-packages),
wcwidth 0.1.7 (/usr/local/lib/python3.7/site-packages),
virtualenv 16.0.0 (/usr/local/lib/python3.7/site-packages),
virtualenv-clone 0.3.0 (/usr/local/lib/python3.7/site-packages),
urllib3 1.24.1 (/usr/local/lib/python3.7/site-packages),
typing 3.6.6 (/usr/local/lib/python3.7/site-packages),
terminaltables 3.1.0 (/usr/local/lib/python3.7/site-packages),
...
Оригинальный ответ
Pip - это просто модуль Python, поэтому просто импортируйте его и вызовите list
:
import pip
pip.main(['list'])
# you can get details on package using show:
pip.main(['show', 'wheel'])
Итак, есть лучший способ:
pip.utils.get_installed_distributions()
возвращает вам список установленных пакетов.
packages = pip.utils.get_installed_distributions()
p = packages[0]
p.project_name
p.version
p.egg_name
p.location
Вы можете увидеть, что pip list
делает из исходного кода здесь
Также get_installed_distributions
принимает целую кучу параметров, чтобы возвращать только локальные пакеты (из текущего virtualenv) и т.д. Пожалуйста, смотрите помощь здесь.
Существует также базовая команда низкого уровня из модуля _vendor
:
[p for p in pip._vendor.pkg_resources.working_set]
Однако get_installed_distributions
обеспечивают более get_installed_distributions
API.
Для полноты здесь идея vittore pip.main()
сфокусирована на захвате stdout. Конечно, использование get_installed_distributions()
является предпочтительным решением.
import contextlib
@contextlib.contextmanager
def capture():
import sys
from cStringIO import StringIO
oldout,olderr = sys.stdout, sys.stderr
try:
out=[StringIO(), StringIO()]
sys.stdout,sys.stderr = out
yield out
finally:
sys.stdout,sys.stderr = oldout, olderr
out[0] = out[0].getvalue()
out[1] = out[1].getvalue()
with capture() as out:
import pip
pip.main(['list'])
print out
['awscli (1.7.45)\nboto (2.38.0) ...
Используйте модуль OS или системный модуль
import os
import subprocess as su
os.system("pip list")
su.call(["pip","list"])