Как устанавливать пакеты в Python — с PIP и без
Прежде чем что-то устанавливать, давайте разберёмся, что такое пакет, чем он отличается от модуля, и как с ним работать. У слова «пакет» применительно к Python два значения.
C одной стороны, пакеты Python — это Py-приложения, дополнения или утилиты, которые можно установить из внешнего репозитория: Github, Bitbucket, Google Code или официального Python Package Index . На сервере пакеты хранятся в .zip и .tar архивах, либо в дополнительной упаковке — «яйцах» (.egg, старый формат) или «колесах» (.whl). В составе пакета, как правило, есть сценарий установки setup.py, который хранит сведения о зависимостях — других пакетах и модулях, без которых пакет работать не будет.
С другой стороны, если речь об архитектуре Python-приложения, пакет — это каталог, внутри которого файл __init__.py и, опционально, другие каталоги и файлы .py . Так большую Python-программу разбивают на пакеты и модули. Модуль — файл с исходным кодом, который можно использовать в других приложениях: как «заготовку» для будущих проектов или как часть библиотеки/фреймворка. Но к теме статьи это прямого отношения не имеет, поэтому дальше мы будем говорить только о пакетах из репозиториев.
Чтобы за секунды устанавливать пакеты со всеми зависимостями, используют менеджер пакетов pip или модуль easy_install . В большинстве случаев рекомендуется использовать pip. И только если у вас есть инфраструктура на пакетах .egg, которые pip не открывает, нужен easy_install.
Установка PIP для Python 3 и 2
Если вы используете виртуальные окружения на базе venv или virtualenv, pip уже установлен. Начиная с Python 3.4 (для Python 2 — с версии 2.7.9) pip поставляется вместе с интерпретатором. Для более ранних версий устанавливать менеджер пакетов нужно вручную. Вариантов два:
- C помощью скрипта get_pip.py — быстро.
- Через setuptools — кроме pip сможем использовать easy_install.
Вариант 1. Скачиваем скрипт get_pip.py и запускаем в консоли. Для этого открываем терминал через Win+R>»cmd»>OK и пишем:
Остальное установщик сделает сам: если нужно, попутно установит wheel (для распаковки .whl-колес) и setuptools. Чтобы запретить инсталляцию дополнительных инструментов, можно добавить в строку ключи —no-setuptools и/или —no-wheels.
Если возникает ошибка, путь к Python не прописан в переменной среды $PATH. Нужно либо найти эту переменную в системном реестре и задать её значение, либо каждый раз указывать полный путь до python.exe, а за ним уже имя исполняемого Py-файла:
Полный путь полезен и в том случае, если у вас на компьютере несколько версий Python и вы ставите пакет для одной из них.
Вариант 2. Скачиваем архив с setuptools из PYPI и распаковываем в отдельный каталог. В терминале переходим в директорию setuptools c файлом setup.py и пишем:
python setup.py install
Обновить pip для Python в Windows можно так:
python pip install -U pip
Если это не работает, нужно добавить путь к папке с pip в $PATH.
Установка пакета в pip
Пора запустить pip в Python и начать устанавливать пакеты короткой командой из консоли:
pip install имя_пакета
При установке в Windows, перед pip нужно добавить «python -m».
Обновить пакет не сложнее:
pip install имя_пакета -U
Если у вас последняя версия пакета, но вы хотите принудительно переустановить его:
pip install —force-reinstall
Посмотреть список установленных пакетов Python можно с помощью команды:
Найти конкретный пакет по имени можно командой «pip search». О других командах можно прочесть в справке, которая выдается по команде «pip help».
Удаление пакета Python
Когда пакет больше не нужен, пишем:
pip uninstall имя_пакета
Как установить пакеты в Python без pip
Формат .egg сейчас используют не часто, поэтому pip его не поддерживает. Модуль easy_install умеет устанавливать как .egg, так и обычные пакеты, но есть у него важные минусы:
- он не удаляет пакеты,
- он может пытаться установить недозагруженный пакет.
Использовать easy_install можно сразу после установки setuptools. Хранится модуль в папке Scripts вашего интерпретатора. Если у вас в $PATH верно прописан путь, ставить пакеты из PYPI можно короткой командой:
Для обновления после install и перед именем пакета нужно ставить ключ -U. Откатиться до нужной версии можно так:
Если нужно скачать пакет из альтернативного источника, вы можете задать URL или локальный адрес на компьютере:
Чтобы узнать об опциях easy_install, запустим его с ключом -h:
Список пакетов, установленных через easy_install, хранится в файле easy-install.pth в директории /libs/site-packages/ вашего Python.
К счастью, удалять установленные через easy_install пакеты можно с помощью pip. Если же его нет, потребуется удалить пакет вручную и стереть сведения о нем из easy-install.pth.
Теперь вы умеете ставить и удалять пакеты для вашей версии Python.
Кстати, для тех, кто изучает Python, мы подготовили список полезных и практичных советов.
Где хранятся модули в Python?

Система модулей даёт возможность логически организовать код на Python. Кроме того, группирование в модули значительно облегчает сам процесс написания кода, плюс делает его более понятным. В этой статье поговорим, что такое модуль в Python, где он хранится и как обрабатывается.
Модуль в Python — это файл, в котором содержится код на Python. Любой модуль в Python может включать в себя переменные, объявления функций и классов. Вдобавок ко всемe, в модуле может содержаться исполняемый код.
Команда import в Python
Позволяет использовать любой файл Python в качестве модуля в другом файле. Синтаксис прост:
import module_1[, module_2[. module_N]Как только Python-интерпретатор встречает команду import, он выполняет импорт модуля, если он есть в пути поиска Python. Что касается пути поиска Python, то речь идёт о списке директорий, в которых интерпретатор выполняет поиск перед загрузкой модуля. Посмотрите на пример кода при использовании модуля math:
import math # Используем функцию sqrt из модуля math print (math.sqrt(9)) # Печатаем значение переменной pi, определенной в math print (math.pi)Помните, что модуль загружается только один раз, вне зависимости от того, какое количество раз вы его импортировали. Таким образом исключается цикличное выполнение содержимого модуля.
Команда from . import
Команда from . import даёт возможность выполнить импорт не всего модуля целиком, а лишь конкретного его содержимого:
# Импортируем из модуля math функцию sqrt from math import sqrt # Выводим результат выполнения функции sqrt. # Нам больше незачем указывать имя модуля print (sqrt(144)) # Но мы уже не можем получить из модуля то, что не импортировали print (pi) # Выдаст ошибкуОбратите внимание, что выражение from . import не импортирует модуль полностью, а лишь предоставляет доступ к объектам, указанным нами.
Команда from . import *
Также в Python мы можем импортировать из модуля переменные, классы и функции за один раз. Чтобы это выполнить, применяется конструкция from . import *:
from math import * # Теперь у нас есть доступ ко всем функция и переменным, определенным в модуле math print (sqrt(121)) print (pi) print (e)Использовать данную конструкцию нужно осторожно, ведь при импорте нескольких модулей можно запутаться в собственном коде.
Так где хранятся модули в Python?
При импорте модуля, интерпретатор Python пытается найти модуль в следующих местах: 1. Директория, где находится файл, в котором вызывается команда импорта. 2. Директория, определённая в консольной переменной PYTHONPATH (если модуль не найден с первого раза). 3. Путь, заданный по умолчанию (если модуль не найден в предыдущих двух случаях).
Что касается пути поиска, то он сохраняется в переменной path в системном модуле sys. А переменная sys.path включает в себя все 3 вышеописанных места поиска.
Получаем список всех модулей Python
Чтобы получить полный список модулей, установленных на ПК, используют команду help("modules") .
Создаём свой модуль в Python
Для создания собственного модуля в Python нужно сохранить ваш скрипт с расширением .py. После этого он станет доступным в любом другом файле. Давайте создадим 2 файла: module_1.py и module_2.py, а потом сохраним их в одной директории. В первом файле запишем:
def hello(): print ("Hello from module_1")А во втором вызовем функцию:
from module_1 import hello hello()После выполнения кода 2-го файла получим:
Hello from module_1Функция dir() в Python
Возвратит отсортированный список строк с содержанием всех имён, определенных в модуле.
# на данный момент нам доступны лишь встроенные функции dir() # импортируем модуль math import math # теперь модуль math в списке доступных имен dir() # получим имена, определенные в модуле math dir(math)
Пакеты модулей в Python
Несколько файлов-модулей с кодом можно объединить в пакеты модулей. Пакет модулей — это директория, включающая в себя несколько отдельных файлов-скриптов.
Представьте, что у нас следующая структура:
|_ my_file.py |_ my_package |_ __init__.py |_ inside_file.pyВ файле inside_file.py определена некоторая функция foo. В итоге, дабы получить доступ к этой функции, в файле my_file нужно выполнить:
from my_package.inside_file import fooТакже нужно обратить внимание на то, есть ли внутри директории my_package файл init.py. Это может быть и пустой файл, сообщающий Python, что директория является пакетом модулей. В Python 3 включать файл init.py в пакет модулей уже не обязательно, но мы рекомендуем всё же делать это, чтобы обеспечить обратную совместимость.
Ликбез по пакетам и шпаргалка по модулям в Python
Как вы, возможно знаете, код на Python хранится в модулях (modules), которые могут быть объединены в пакеты (packages). Это руководство призвано подробно рассказать именно о пакетах, однако совсем не упомянуть модули нельзя, поэтому я немного расскажу и о них. Многое из того, что применимо к модулям, справедливо и для пакетов, особенно если принять во внимание тот факт, что каждый, как правило, ведёт себя как модуль.
Кратко о модулях
Модуль в Python — это файл с кодом. Во время же исполнения модуль представлен соответствующим объектом, атрибутами которого являются:
- Объявления, присутствующие в файле.
- Объекты, импортированные в этот модуль откуда-либо.
При этом определения и импортированные сущности ничем друг от друга не отличаются: и то, и другое — это всего лишь именованные ссылки на некоторые объекты первого класса (такие, которые могут быть переданы из одного участка кода в другой как обычные значения).
Такое единообразие удобно, например, при рефакторинге: мы можем разделить один разросшийся модуль на несколько, а потом импортировать вынесенные определения в оригинальный модуль. При этом с точки зрения внешнего наблюдателя переработанный модуль будет иметь те же атрибуты, которые имел до внесения изменений, а значит у пользователей модуля ничего в коде не сломается.
Модули и видимость содержимого
В Python нет настоящего сокрытия атрибутов объектов, поэтому и атрибуты объекта модуля так или иначе всегда доступны после импорта последнего. Однако существует ряд соглашений, которые влияют на процесс импортирования и поведение инструментов, работающих с кодом.
Так атрибуты, имя которых начинается с одиночного подчёркивания, считаются как бы помеченными "для внутреннего использования", и обычно не отображаются в IDE при обращению к объекту "через точку". И linter обычно предупреждает об использовании таких атрибутов, мол, "небезопасно!". "Опасность" состоит в том, что автор кода имеет полное право изменять состав таких атрибутов без уведомления пользователей кода. Поэтому программист, использовавший в своём коде приватные части чужого кода рискует в какой-то момент получить код, который перестанет работать при обновлении сторонней библиотеки.
Итак, мы можем определять публичные атрибуты модуля, приватные атрибуты (так называют упомянутые выше атрибуты "для внутреннего пользования"). И данное разделение касается не только определений, содержащихся в самом модуле, но и импортируемых сущностей. Ведь все импортированные объекты становятся атрибутами и того модуля, в который они импортированы.
Есть и третья группа атрибутов — атрибуты, добавляемые в область видимости при импортировании всего содержимого модуля ("со звёздочкой", from module import * ). Если ничего явно не указывать, то при таком импортировании в текущую область видимости добавятся все публичные атрибуты модуля. Помимо данного умолчания существует и возможность явно указать, что конкретно будет экспортировано при импорте со звёздочкой. Для управления названным методом импорта существует атрибут __all__ , в который можно положить список (а ещё лучше — кортеж) строк с именами, которые будут экспортироваться.
Живой пример видимости атрибутов модулей.
Рассмотрим пример, демонстрирующий всё вышеописанное. Пусть у нас будет два файла:
# Файл "module.py" from other_module import CAT, DOG as _DOG, _GOAT FISH = 'fish' MEAT = 'meat' _CARROT = 'carrot' __all__ = ('FISH', '_CARROT')# Файл "other_module.py" CAT = 'cat' DOG = 'dog' _GOAT = 'goat'Рассмотрим сначала обычный импорт import module . Если импортировать модуль таким образом, то IDE, REPL и остальные инструменты "увидят" у модуля следующие атрибуты:
- FISH , MEAT т.к. имена констант — публичные,
- CAT , т.к. константа импортирована под публичным именем.
А эти атрибуты не будут видны:
- _DOG , т.к. при импортировании константа переименована в приватной манере,
- _GOAT , т.к. импортирована по своему приватному имени (тут линтер может и поругать за обращение к приватному атрибуту модуля!),
- _CARROT , ибо приватная константа.
Импорт import other_module я не рассматриваю как тривиальный случай.
Теперь рассмотрим импорт всего содержимого module:
from module import *
После импортирования в текущей области видимости мы получим ровно два новых имени: FISH и _CARROT — именно они перечислены в атрибуте __all__ . Заметьте, что в данном случае при массовом импорте добавится даже приватный атрибут, потому что он явно указан!
Последствия импорта from other_module import * тоже очевидны и я их не рассматриваю.
Наконец-то, пакеты!
Пакет в Python — директория с обязательным модулем __init__.py . Остальное содержимое опционально и может включать в себя и модули, и другие пакеты.
Импортирование пакетов
Пакет с единственным модулем __init__.py при импорте ведёт себя как обычный модуль. Содержимое инициализирующего модуля определяет атрибуты объекта пакета.
Прочие модули пакета и вложенные пакеты не импортируются автоматически вместе с пакетом-родителем, но могут быть импортированы отдельно с указанием полного имени. Важный момент: при импортировании вложенного модуля всегда сначала импортируются модули инициализации всех родительских пакетов (если оные ещё ни разу не импортировались, но об этом я расскажу ниже).
Рассмотрим, к примеру, следующую структуру директорий и файлов:
Когда мы импортируем модуль submodule.py , то фактически происходит следующее (именно в таком порядке):
- загружается и выполняется модуль package/__init__.py ,
- загружается и выполняется package/subpackage/__init__.py ,
- наконец, импортируется package/subpackage/submodule.py .
При импорте package.module предварительно загружается только package/__init__.py .
Так что же, если мы загрузим парочку вложенных модулей, то для каждого будет выполняться загрузка всех __init__.py по дороге? Не будет! Подсистема интерпретатора, отвечающая за загрузку модулей, кэширует уже загруженные пакеты и модули. Каждый конкретный модуль загружается ровно один раз, в том числе и инициализирующие модули __init__.py (короткие имена модулей хоть и одинаковы, но полные имена всегда разные). Все последующие импортирования модуля не приводят к его загрузке, только лишь нужные атрибуты копируются в соответствующие области видимости.
Пакеты и __all__
В целом атрибут __all__ в модуле инициализации пакета ведёт себя так же, как и в случае с обычным модулем. Но если при импорте пакета "со звёздочкой" среди перечисленных имён встретится имя вложенного модуля, а сам модуль не окажется импортирован ранее в этом же __init__.py , то этот модуль импортируется неявно! Очередной пример это продемонстрирует.
Вот структура пакета:
Файл же package/__init__.py содержит следующее (и только это!):
__all__ = ('a', 'b')
А импортируем мы from package import * . В области видимости у нас окажутся объекты модулей a и b под своими именами (без полного пути, то есть без package. ). При этом сами модули в коде нигде явно не импортируются! Такая вот "автомагия".
Указанный автоматизм достаточно ограничен: не работает "вглубь", например — не импортирует "через звёздочку" указанные модули и подпакеты. Если же вам вдруг такого захочется, вы всегда сможете на соответствующих уровнях в __init__.py сделать from x import * и получить в корневом пакете плоскую область видимости со всем нужным содержимым. Но такое нужно довольно редко, потому что "не помогает" ни IDE, ни ручному поиску по коду. Впрочем, знать о фиче и иметь её в виду — не вредно, как мне кажется.
Изучайте Python на Хекслете Первые курсы в профессии Python-программист доступны бесплатно сразу после регистрации. Начните сегодня, учитесь в комфортном для вас темпе.
Пакеты, модули и точки входа
С модулем __init__.py разобрались. Настала очередь модуля __main__.py . Этот модуль позволяет сделать пакет исполняемым посредством вызова python -m … . Те из вас, кому знакомо оформление точки входа в модулях, могут догадаться, откуда ноги растут у магического выражения __name__ == '__main__' — да, отсюда! Для остальных напоминаю: чтобы модуль сделать "исполняемым, но не при импорте", в конец модуля дописывается конструкция
if __name__ == '__main__': main() # тут что-то выполняем
У модуля, который скармливается интерпретатору напрямую ( python file.py ) или в роли претендента на запуск ( python -m module ), атрибут __name__ будет содержать то самое магическое '__main__' . А в остальное время атрибут содержит полное имя модуля. С помощью условия, показанного выше, модуль может решить, что делать при запуске.
У пакетов роль атрибута выполняет специальный файл __main__.py . Когда мы запустим пакет через python path/to/package или python -m package , интерпретатор будет искать и выполнять именно этот файл.
Более того, модули __main__ нельзя импортировать обычным способом, поэтому можно не бояться случайного импорта и писать команды прямо на верхнем уровне: всё равно странно в модуле с именем __main__ проверять, что его имя равно __main__ (хе-хе!).
А ещё модуль __main__.py удобен тем, что его можно класть в корень вашего проекта, после чего запускать проект можно будет с помощью команды python . ! Лаконично, не правда ли?
PEP 420, или неявные пространства имён
Раз уж развёл ликбез, расскажу и про эту штуку.
Долгое время в Python пакеты были обязаны иметь файл __init__.py — наличие этого файла позволяло отличить пакет от обычной директории с модулями (с которыми Python работать не мог). Но с версии Python3.3 вступил в силу PEP 420 , позволяющий создавать пространства имён "на вырост".
Теперь вы можете создавать пакет без __init__.py , и такой пакет сможет существовать полноценно, разве что при импорте содержимого не будет производиться инициализация. Но, конечно же, данное изменение делалось не с целью сэкономить на файлах. Подобные пакеты могут встречаться в путях поиска пакетов (о поиске пакетов я ниже расскажу) более одного раза: все встреченные структуры с общим корневым именем при загрузке схлопнутся в одно пространство имён.
Тут стоит отметить, что с полноценными пакетами подобное не срабатывало ранее и не будет работать в будущем. Если среди путей пакет с модулем инициализации находится в первый раз, все последующие пакеты с тем же именем будут проигнорированы. Это защищает вас от смешивания сторонних пакетов с системными. И даже просто от ошибок именования: назвав пакет так же, как называется встроенный пакет или модуль, вы получите ошибку — ваши определения не будут импортироваться.
Пакеты — пространства имён (Namespace Packages, NP) — а именно так называются пакеты без инициализации — не могут объединяться с полноценными пакетами, поэтому добавить что-то в системный пакет вам также не удастся. И тут всё защищено!
Какая же польза от неявных пространств имён? А вы представьте себя авторами, скажем, игрового движка. Вы хотите весь код держать в общем пространстве имён engine , но при этом не желаете, чтобы весь код поставлялся одним дистрибутивом (не каждому же пользователю нужны все-все компоненты движка). С NP вы можете в нескольких дистрибутивах использовать общее корневое имя engine , но разные подпакеты и подмодули. А на выходе вы получите возможность делать импорты вида
from engine import graphics, sound
Важно: помните, если встретятся обычный пакет и NP с одинаковым именем, то победит обычный пакет! А NP, сколько бы их не было, не будут загружены!
Циклические импорты
Если вдруг вы захотите в один модуль импортировать другой, а другой захочет, пусть даже и не напрямую, импортировать первый, то вы получите ImportError . Потому что у вас случится циклический импорт. Про оный нужно просто знать и стараться архитектурить код так, чтобы циклов не случалось.
Если же приспичивает, и импортировать что-то "ну очень нужно", то можно попробовать обойтись локальным импортом:
### foo.py import bar A = bar(42)
### bar.py # import foo — тут не импортируем def bar(x): return x + 1 def baz(): import foo # а тут уже можно return foo.A
Да, это костыль. Но иногда полезный. В идеале — до ближайшего большого рефакторинга. Поэтому настраивайте linter на ловлю локальных импортов и стремитесь убирать такие костыли хоть когда-нибудь!
Поиск пакетов и модулей
Пайтон ищет модули и пакеты в директориях, во время исполнения перечисленных в списке sys.path — по порядку от первого пути к последнему.
В этом списке пути до стандартных библиотек обычно расположены раньше, чем директории со сторонними пакетами, чтобы нельзя было случайно заменить стандартный пакет сторонним (помним: кто первый, того и тапки — среди нескольких с одинаковыми именами загружается первый попавшийся пакет).
В списке путей (обычно в начале) присутствует и путь '' , означающий текущую директорию. Это, в свою очередь, означает, что модули и пакет в текущем проекте имеют больший приоритет.
Обычно пути трогать не нужно, всё вполне нормально "работает само". Но если очень хочется, то путей у вас несколько:
- Использовать переменную окружения PYTHONPATH (значение — строка с путями, разделёнными символом : ),
- Во время исполнения изменить sys.path .
Первый способ — простой и понятный. Не сложнее добавления пути до исполняемых файлов в PATH (даже синтаксис тот же).
Второй способ — сложный и требующий внимательности. Дело в том, что sys.path нужно изменять максимально рано — где-нибудь в точке входа. Если не торопиться менять sys.path , то что-то уже может успеть загрузиться до того, как вы перестроите пути для поиска пакетов. А ведь эта загрузка может произойти в другом потоке исполнения! Отлаживать проблемы с очерёдностью загрузки модулей сложно. Лучше просто их не создавать.
Кстати, когда вы используете виртуальные окружения, sys.path будет содержать пути до локальных копий стандартных библиотек. Именно это позволяет виртуальному окружению быть самодостаточным (работать на любой машине с подходящей ОС — даже без установленного в систему Python!).
Что не было раскрыто?
Я специально не стал рассказывать про
- создание модулей и пакетов на лету (без использования файлов исходников);
- загрузку модулей не с диска, а из других источников;
- расширение подсистемы импортирования с целью загрузки в виде объектов-модулей чего-то, не являющегося кодом вовсе (XML, CSV, JSON).
Темы эти насколько интересны, настолько и велики. На наше счастье, самим разбираться в такой тонкой и сложной машинерии приходится редко. Мы просто пользуемся готовыми магическими артефактами, а зачаровывают их другие 🙂 Если же вы захотите научиться магии, документация вам в руки.
Как найти местоположение модуля Python?
Скрипт на Python использует некий модуль. С помощью какой команды можно найти его местоположение на диске машины?
Отслеживать
9,366 4 4 золотых знака 40 40 серебряных знаков 56 56 бронзовых знаков
задан 23 апр 2017 в 10:11
369 2 2 золотых знака 7 7 серебряных знаков 18 18 бронзовых знаков
find . -name "нейкий модуль"
23 апр 2017 в 10:23
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
import some_module import sys import os for path in sys.path: if os.path.exists(os.path.join(path, 'some_module')): print('some_module is here: <>'.format(path))
"Трюк" здесь заключается в том, что где бы интерпретатор не встретил строку
from somewhere import something
он ищет somewhere в sys.path . И если не находит - выбрасывается исключение ImportError . При этом при запуске интерпретатора, текущий путь (или при запуске скрипта python path/to/script.py путь path/to ) добавляется в sys.path .
2-й вариант (попроще):
import some_module print(some_module.__file__) >>> import openpyxl >>> print (openpyxl.__file__) D:\Python\lib\site-packages\openpyxl-2.3.0_b1-py2.7.egg\openpyxl\__init__.pyc >>>
Но 2-й вариант можно "обмануть", явно определив в модуле переменную __file__




