https://habr.com/ru/company/otus/blog/475392/- Блог компании OTUS. Онлайн-образование
- Python
- Программирование
- Машинное обучение
И снова здравствуйте. В преддверии старта нового потока по курсу «Machine Learning», хотим поделиться переводом статьи, которая имеет довольно косвенное отношение к ML, но наверняка будет полезна подписчикам нашего блога.
Мариатта — разработчик из Канады, спросила в Твиттере о
python -m pip, попросив рассказать об этой идиоме и объяснить принцип ее работы.
Недавно я узнала, что нужно писать python -m pip вместо обычного pip install, но теперь я не могу вспомнить от кого я это услышала. Наверное, от @brettsky или @zooba. У кого-нибудь из вас есть пост в блоге, чтобы я могла поделиться им с читателями?
— Мариатта (@mariatta
) 29 октября 2019 г. (https://twitter.com/mariatta/status/1189243515739561985?ref_src=twsrc%5Etfw)
Я не уверен, что именно я сказал Мариатте о
python -m pip, но есть все шансы, что это был именно я, поскольку я же просил, чтобы эта инструкция для установки пакетов с помощью
PyPI писалась именно так с 2016 года. Итак, эта статья должна пояснить, что такое
python -m pip и почему вы должны использовать именно ее при запуске
pip.
Что такое python -m pip?
Для начала,
python -m pip выполняет pip с помощью той версии Python, которую вы указали для инструкции python. Таким образом,
/usr/bin/python3.7 -m pip
значит, что вы выполните
pip для интерпретатора, расположенного в
/usr/bin/python3.7
. Вы можете прочитать
документацию про флаг
-m
, если вы не знаете, как он работает (кстати, он крайне полезный).
Зачем использовать python -m pip вместо pip/pip3?
Вы можете сказать: «Ладно, но почему я не могу просто воспользоваться
pip, запустив команду
pip?» Ответом будет: «Да, но контролировать вы ее будете меньше». Я объясню, что значит «контролировать меньше» на примере.
Предположим, у меня установлены две версии Python, например, Python 3.7 и 3.8 (это очень распространено среди людей, которые работают на Mac OS или Linux, не говоря уже о том, что вы возможно захотели поиграться с Python 3.8, и у вас уже стоял Python 3.7). Итак, если вы введете
pip в терминале, для какого интерпретатора Python вы установите пакет?
Без более подробной информации ответа вы не узнаете. Сначала вам нужно будет понять, что лежит в PATH, то есть
/usr/bin
идет первым или же
/usr/local/bin
(которые являются самыми распространенными местами для установки Python, кстати обычно
/usr/local/
идет первым). Итак, вы помните, где вы установили Python 3.7 и 3.8 и что это были разные каталоги, и вы будете знать, что пришло в PATH первым. Предположим, что вы установили оба вручную, возможно в вашей системе был уже предустановлен Python 3.7.3, и вы установили Python 3.7.5. В этом случае обе версии Python устанавливаются в
/usr/local/bin
. Можете ли вы сказать мне теперь, к чему теперь привязан
pip?
Ответ вы не знаете. Если вы не знаете, когда устанавливали каждую версию, и понимаете, что последняя версия
pip была записана в
/usr/local/bin/pip
, но вы не знаете, какой интерпретатор будет использоваться для команды
pip. Теперь вы можете сказать: «Я всегда ставлю самые последние версии, так что это значит, что Python 3.8.0 будет установлен последним, поскольку он новее, чем, допустим, 3.7.5". Хорошо, но что происходит, когда выходит Python 3.7.6? Ваш
pip использовался бы уже не из Python 3.8, а из Python 3.7.
Когда вы используете
python -m pip с конкретным интерпретатором python, который вам нужен, вся неопределенность исчезает. Если я пишу
python3.8 -m pip, я точно знаю какой
pip будет использован и что пакет будет установлен для Python 3.8 (то же самое было бы, если бы я указал python3.7).
Если вы пользуетесь Windows, то у вас есть дополнительный стимул использовать
python -m pip, поскольку он позволяет
pip обновлять себя. В основном, потому что
pip.exe считается запущенным, когда вы пишете
pip install --upgrade pip. В этот момент Windows не позволит вам переустановить
pip.exe. Однако если вы делаете
python-m pip install --upgrade pip, вы обходите эту проблему, поскольку запускается
python.exe, а не
pip.exe.
А что происходит, когда я нахожусь в активированной среде?
Обычно, когда я объясняю суть этой статьи людям, обязательно находится кто-то, кто скажет: «Я всегда использую виртуальную среду, и это ко мне не относится». Что ж, для начала хорошо бы ВСЕГДА использовать виртуальную среду! (Я расскажу, почему я так думаю, в одной из своих следующих статей!) Но если честно, то я бы все еще настаивал на использовании
python -m pip, даже если, строго говоря, это не нужно.
Во-первых, если вы пользуетесь Windows, вам все равно захочется использовать
python-m pip, чтобы вы в своей среде могли обновить
pip.
Во-вторых, даже если вы используете другую операционную системы, я бы сказал, что все равно нужно пользоваться
python-m pip, поскольку он будет работать независимо от ситуации. Он предупредит вас об ошибке, если вы забудете активировать среду, а любой человек, который за вами будет наблюдать, будет перенимать лучшие практики. И лично я не считаю, что экономия 10 нажатий на клавиатуру – весомая цена для неиспользования хорошей практики. А еще эта команда поможет вам предотвратить ошибки при написании сценариев автоматизации, которые будут выполнять заведомо некорректные операции, если вы забудете активировать среду.
Лично я, когда пользуюсь любым инструментом, работа которого зависит от того, каким интерпретатором он запускается, всегда пользуюсь
-m
, вне зависимости того, активирована виртуальная среда или нет. Мне всегда важно понимать, какой интерпретатор Python я использую.
ВСЕГДА пользуйтесь средой! Не ставьте все подряд в глобальный интерпретатор!
Когда мы говорим о том, как избежать путаницы при установке в Python, хочу подчеркнуть, что мы вообще не должны устанавливать ничего в глобальный интерпретатор Python, когда работаем локально (контейнеры – это совсем другое дело)! Если это предустановленный Python вашей системы, то в случае, если вы установите какую-то несовместимую версию библиотеки, на которую опирается ваша ОС, то фактически сломаете систему.
Но даже если вы установите отдельно для себя копию
python, я все равно настоятельно не рекомендую ставить прямо в нее при локальной разработке. В конечном счете в своих проектах вы будете использовать различные пакеты, которые могут друг с другом конфликтовать, и у вас не будет четкого представления о зависимостях внутри ваших проектов. Гораздо лучше использовать среды, чтобы изолировать отдельные проекты и инструменты для них друг от друга. В сообществе Python используются два типа сред: виртуальные среды и conda среды. Существует даже специальный способ изолированной установки инструментов Python.
Если вам нужно установить инструмент
Для изолированной установки инструмента, я могу порекомендовать использовать
pipx. Каждый инструмент получит свою собственную виртуальную среду, чтобы не конфликтовать с другими. Таким образом, если вы хотите иметь всего одну установку, к примеру,
Black, вы можете работать, не сломав случайно свою единственную установку
mypy.
Если вам нужна среда для проекта (и вы не пользуетесь conda)
Когда нужно создать среду для проекта, лично я всегда обращаюсь к
venv и виртуальным средам. Она включена в
stdlib Python, поэтому всегда доступна с помощью
python-m venv (если, конечно, вы не используете Debian или Ubuntu, в этом случае вам может потребоваться установить пакет
python3-venv apt). Немножко истории: Я фактически удалил старую команду
pyvenv, которую Python устанавливал для создания виртуальных сред с помощью
venv, по тем же причинам, почему нужно пользоваться
python -m pip вместо
pip. То есть непонятно для какого интерпретатора вы создали виртуальную среду при помощи старой команды
pyvenv. И помните о том, что вам не нужно активировать среду, чтобы использовать интерпретатор содержащийся в ней, ведь
.venv/bin/python
работает так же хорошо, как активация среды и ввод команды
python.
Сегодня некоторые разработчики по-прежнему отдают предпочтение
virtualenv, поскольку она доступна на Python 2 и в ней есть некоторые дополнительные функции. Лично меня мало интересуют дополнительные функции, и наличие интегрированной
venv означает, что мне не нужно использовать
pipx для установки
virtualenv на каждой машине. Но если
venv не отвечает вашим потребностям, и вы хотите виртуальную среду, то посмотрите, предлагает ли
virtualenv то, что вам нужно.
Если вы используете conda
Если вы используете
conda, то можете использовать среды
conda для получения того же эффекта, который могут предложить виртуальные среды, предоставляемые
venv. Я не собираюсь вдаваться в то, нужно ли вам использовать conda или venv в вашей конкретной ситуации, но если вы используете
conda, то знаете, что вы можете (и должны) создавать среды
conda для своей работы, вместо того чтобы устанавливать все подряд в свою системную установку. Так вы сможете получить четкое понимание того, какие зависимости есть у вашего проекта (и это хорошая причина, чтобы использовать
miniconda вместо полноценной
anaconda, поскольку в первой меньше десятой части объема последней).
Всегда есть контейнеры
Работать в контейнере – это способ не разбираться со средой вообще, так как вся ваша «машина» станет отдельной средой. До тех пор, пока вы не установили Python в систему контейнера, вы должны спокойно иметь возможность сделать глобальную установку, чтобы ваш контейнер оставался простым и понятным.
Повторюсь, чтобы вы действительно поняли суть…
Не устанавливайте ничего в свой глобальный интерпретатор Python! Всегда старайтесь использовать среду для локальной разработки!
Я уже не могу сказать, сколько раз мне приходилось помогать кому-то, кто думал, что pip устанавливал в один интерпретатор Python, а на самом деле устанавливал в другой. И это неизмеримое количество также относится к тем моментам, когда люди ломали всю систему или задавались вопросом, почему они не смогли установить что-то, что противоречило какой-то другой вещи, которую они поставили ранее для другого проекта и т.д. из-за того, что они не потрудились настроить среду на своей локальной машине.
Поэтому, чтобы и вы и я могли спать спокойно, используйте
python-m pip и старайтесь всегда использовать среду.