Проверьте, установлен ли пакет Python

Какой хороший способ проверить, установлен ли пакет в Python script? Я знаю это легко от переводчика, но мне нужно сделать это в script.

Я предполагаю, что могу проверить, существует ли каталог в системе, созданный во время установки, но я чувствую, что есть лучший способ. Я пытаюсь убедиться, что пакет Skype4Py установлен, и если нет, я его установлю.

Мои идеи для выполнения проверки

  • проверить каталог на типичном пути установки
  • попробуйте импортировать пакет, и если исключение выбрано, установите пакет

Ответ 1

Если вы имеете в виду python script, просто выполните что-то вроде этого:

try:
 import mymodule
except ImportError, e:
 pass # module doesn't exist, deal with it.

Ответ 2

Обновленный ответ

Лучший способ сделать это:

import subprocess
import sys

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in reqs.split()]

Результат:

print(installed_packages)

[
    "Django",
    "six",
    "requests",
]

Проверьте, установлен ли requests:

if 'requests' in installed_packages:
    # Do something

Почему так? Иногда вы сталкиваетесь с именами приложений. Импорт из пространства имен приложения не дает полной картины того, что установлено в системе.

Обратите внимание, что предлагаемое решение работает:

  • При использовании pip для установки из PyPI или из любого другого альтернативного источника (например, pip install http://some.site/package-name.zip или любого другого типа архива).
  • При установке вручную с помощью python setup.py install.
  • При установке из системных репозиториев, например sudo apt install python-requests.

Случаи, когда это может не работать :

  • При установке в режиме разработки, например python setup.py develop.
  • При установке в режиме разработки, например pip install -e /path/to/package/source/.

Старый ответ

Лучший способ сделать это:

import pip
installed_packages = pip.get_installed_distributions()

Для пунктов> = 10.x используйте:

from pip._internal.utils.misc import get_installed_distributions

Почему так? Иногда вы сталкиваетесь с именами приложений. Импорт из пространства имен приложения не дает полной картины того, что установлено в системе.

В результате вы получите список объектов pkg_resources.Distribution. В качестве примера смотрите следующее:

print installed_packages
[
    "Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
    "six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
    "requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
]

Составьте список этого:

flat_installed_packages = [package.project_name for package in installed_packages]

[
    "Django",
    "six",
    "requests",
]

Проверьте, установлен ли requests:

if 'requests' in flat_installed_packages:
    # Do something

Ответ 3

Начиная с Python 3.3, вы можете использовать метод find_spec() method

import importlib.util

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")

Ответ 4

Если вы хотите получить чек от терминала, вы можете запустить

pip3 show package_name

и если ничего не будет возвращено, пакет не будет установлен.

Если вы хотите автоматизировать эту проверку, чтобы, например, вы могли установить ее, если она отсутствует, вы можете иметь следующее в bash script:

pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
   echo "Installed" #Replace with your actions
else
   echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi

Ответ 5

Как продолжение этого ответа:

Для Python 2. * pip show <package_name> выполнит ту же задачу.

Например, pip show numpy вернет следующее или подобное:

Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: [email protected]
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires: 
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy

Ответ 6

Вы можете использовать модуль pkg_resources из setuptools. Например:

import pkg_resources

package_name = 'cool_package'
try:
    cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
    print('{} not installed'.format(package_name))
else:
    print(cool_package_dist_info)

Обратите внимание, что есть разница между модулем Python и пакетом Python. Пакет может содержать несколько модулей, а имена модулей могут не совпадать с именем пакета.

Ответ 7

Я хотел бы добавить некоторые мои мысли/выводы на эту тему. Я пишу script, который проверяет все требования к пользовательской программе. Существует много проверок с модулями python.

Там немного проблема с

try:
   import ..
except:
   ..

решение. В моем случае один из модулей python, называемый python-nmap, но вы импортируете его с помощью import nmap и, как видите, несоответствие имен. Поэтому тест с приведенным выше решением возвращает результат False, а также импортирует модуль при попадании, но, возможно, нет необходимости использовать большую память для простого теста/проверки.

Я также обнаружил, что

import pip
installed_packages = pip.get_installed_distributions()

installed_packages будет только пакеты установлены с помощью pip. В моей системе pip freeze возвращается через 40 модули python, а installed_packages имеет только 1, тот, который я установил вручную (python-nmap).

Другое решение, ниже которого я знаю его , может не иметь отношения к вопросу, но я считаю хорошей практикой сохранить отдельную тестовую функцию от той, которая выполняет установить его может быть полезно для некоторых.

Решение, которое сработало для меня. Он основан на этом ответе Как проверить, существует ли модуль python, не импортируя его

from imp import find_module

def checkPythonmod(mod):
    try:
        op = find_module(mod)
        return True
    except ImportError:
        return False

ПРИМЕЧАНИЕ. Это решение не может найти модуль по имени python-nmap тоже, я должен использовать nmap вместо этого (легко жить с), но в этом случае модуль не будет загружен в память вообще.

Ответ 8

Если вы хотите, чтобы ваш скрипт установил недостающие пакеты и продолжил, вы можете сделать что-то вроде этого (на примере модуля 'krbV' в пакете 'python-krbV'):

import pip
import sys

for m, pkg in [('krbV', 'python-krbV')]:
    try:
        setattr(sys.modules[__name__], m, __import__(m))
    except ImportError:
        pip.main(['install', pkg])
        setattr(sys.modules[__name__], m, __import__(m))

Ответ 9

Быстрый способ - использовать инструмент командной строки python. Просто введите import <your module name> Вы видите ошибку, если модуль отсутствует.

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> import sys
>>> import jocker
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named jocker
$

Ответ 10

Хммм... ближе всего к удобному ответу я использовал командную строку для попытки импорта. Но я предпочитаю даже избегать этого.

Как насчет "заморозить пипс | grep pkgname '? Я попробовал это, и это работает хорошо. Он также показывает версию, которая у него есть, и установлена ли она под управлением версиями (установка) или редактируемой (разработка).

Ответ 11

Вариант Go # 2. Если выбрано ImportError, тогда пакет не установлен (или не находится в sys.path).