Работа с модулями и виртуальными средами

В последнем посте мы рассмотрели советы о том, как структурировать код, рекомендации по форматированию PEP 8 и еще несколько принципов кодирования.



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

Пакеты

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

Итак, что содержится в пакете?

Помимо кода, который вы хотите повторно использовать в других проектах, пакет состоит из файлов README.md, LICENSE и setup.py.

  • README.md (уценка) - содержит информацию о вашем пакете, которая может быть использована для понимания того, что ваш пакет делает.
  • LICENSE - это лицензионное соглашение или условия использования. Используйте это, чтобы сообщить другим, нужно ли им отдать вам должное, могут ли они использовать его для коммерческих приложений, могут ли они вносить изменения и распространять, если вы не несете ответственности за ущерб и т. Д.
  • setup.py - запускается всякий раз, когда вы впервые устанавливаете пакет. Он сообщает Python о любых зависимостях и предоставляет метаданные о вашем пакете, которые будут отображаться пользователям из репозитория пакетов.

Из всего этого setup.py является наиболее важным, поскольку это способ установки вашего пакета.

Когда я читаю лицензии, я всегда смеюсь над тем, когда кто-то включает «Не несет ответственности за нанесенный ущерб», когда программа печатает «Hello, World!»

Смеется в сторону, это так же важно, как и setup.py, когда вы делитесь своим кодом со всем миром. Хотя вы можете оказать миру услугу, написав полезную программу, если она не работает с определенной версией Python и ваша программа повреждает систему, вы будете нести ответственность, даже если конечный пользователь был тем, кто в конечном итоге решил запустить вашу программу на своем компьютере.

У Python есть тысячи доступных для использования пакетов. Я использовал пакеты для подключения к серверам LDAP для выполнения работы с пользователями, пакеты для удаленного подключения по SSH к другому компьютеру для выполнения сценариев, пакеты для запуска веб-серверов и многое другое.

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

Команда Pip

Мы можем загружать пакеты с помощью команды pip. pip использует онлайн-репозиторий пакетов, называемый Python Package Index, или для краткости Pypi.

В более старых версиях Python pip не был включен. В операционных системах Linux вы можете установить пакет с именем python-pip или python36-pip, чтобы установить его.

pip - простая утилита. Подобно apt, yum или brew, вы можете искать пакеты, получать информацию о пакетах или устанавливать и удалять пакеты.

Вот несколько наиболее распространенных команд, которые я использую:

  • pip search <package_name> - поиск пакетов для установки
  • pip list - список всех установленных пакетов
  • pip info <package_name> - получить информацию об установленном пакете
  • pip freeze - предоставляет список установленных пакетов в формате требований (подробнее об этом позже)
  • pip install <package_name> - устанавливает пакет или список пакетов через запятую; используйте pip install -U <package_name> для обновления пакета до последней версии.
  • pip uninstall <package_name> - удаляет пакет или список пакетов, разделенных запятыми

Ранее в этой серии я говорил, что использовал Черный для форматирования своего кода. Обычно это первый пакет, который я устанавливаю на все свои компьютеры. Идея исходит из знаменитого высказывания Генри Форда о цвете модели T.

Если вы хотите использовать его, вы можете установить его с помощью следующей команды:

pip install black

Существуют и другие средства форматирования, которые вы можете использовать, но меня не слишком заботит, как они делают отступ в моем коде. Это полностью субъективно, поэтому я настоятельно рекомендую вам проверить их все, прежде чем выбирать один.

Кевин Петерс уже написал отличную статью о средствах форматирования Python, поэтому я отсылаю вас к его статье, если вы хотите провести собственное исследование.



Виртуальные среды

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

Например, проект A зависит от Django 1.11, а проект B - от Django 2.1. Система будет обрабатывать только одну версию Django за раз, что означает, что один из наших проектов будет сломан, когда мы попытаемся исправить другой.

Войдите в виртуальные среды.

Виртуальные среды позволяют вам создать локальный каталог Python проекта для хранения всех ваших зависимостей для этого проекта. Это означает, что проект A может иметь локально установленный Django 1.11, в то время как проект B может иметь собственный локально установленный Django 2.1.

То, как это работает, не вдаваясь в технические подробности, заключается в том, что Python создает папку, в которой исполняемые файлы связаны с версией Python, из которой он был создан. Это позволяет использовать один и тот же интерпретатор Python в нескольких проектах с несколькими зависимостями.

Довольно круто, правда? К сожалению, эта замечательная утилита - палка о двух концах. Если вы обновите интерпретатор Python, создавший эту виртуальную среду, это может нарушить ваш код или виртуальную среду. Некоторые пакеты разработаны только для определенной версии Python и используют устаревшие функции. При обновлении до версии, в которой удалены эти устаревшие функции, пакет прерывается. Не круто, правда? Конечно, это могло произойти в любом случае, но это все еще серьезный подтекст. Помните, что вы не копируете интерпретатор Python, а просто делаете обратную ссылку на него.

Как создать виртуальную среду?

Опять же, если вы использовали один из тех дистрибутивов Linux, в которых не был установлен pip, скорее всего, вам также потребуется установить пакет виртуальной среды. Вы можете сделать это, установив пакет с именем python-venv или python36-venv. (Если вам интересно, некоторые дистрибутивы, такие как CentOS по умолчанию python, означают Python 2, а python36 означает Python 3.6.)

После того, как вы его установили, вы должны использовать cd, чтобы перейти в каталог, который должен содержать ваш проект, а затем создать каталог виртуальной среды внутри папки вашего проекта с помощью этой команды:

python -m venv venv

Это говорит python использовать -module venv для создания виртуальной среды в папке с именем venv. Вы можете присвоить папке venv любое имя, но в большинстве учебных пособий и проектов, если на то пошло, используется venv. В системах * nix допустимо использовать .venv, чтобы скрыть папку.

Если вы хотите использовать версию Python, отличную от той, которая используется по умолчанию для вашей системы, используйте вместо нее эту команду:

/path/to/other/pythonx.x -m venv venv

Если вы заглянете во вновь созданную папку venv, вы увидите следующие папки:

  • bin/ - содержит ссылки на исполняемые файлы Python, используемые для этой виртуальной среды.
  • lib/ - включает пакеты, которые были установлены в этой виртуальной среде, такие как Django или Black
  • include/ - содержит файлы заголовков C, которые используются для компиляции пакетов Python
  • pyvenv.cfg - содержит информацию о конфигурации этой виртуальной среды.
  • pip-selfcheck.json - содержит метаданные о pip в виртуальной среде.

После того, как вы создали виртуальную среду, вам необходимо активировать виртуальную среду; в противном случае вы по-прежнему будете использовать и устанавливать пакеты в интерпретатор Python по умолчанию. Вы можете сделать это с помощью этой команды:

В Linux и macOS:
source venv/bin/activate

В Windows:
venv/bin/activate

В Windows activate - это ссылка на activate.bat, которая активирует виртуальную среду. В системах * nix activate - это сценарий оболочки, который делает то же самое при использовании в качестве аргумента встроенной команды source.

Вы узнаете, что он активирован, когда перед командной строкой появится префикс (venv).

Чтобы выйти из командной строки виртуальной среды, вы можете использовать deactivate.

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

Линтеры - это инструменты, используемые для статического анализа вашего кода; они гарантируют, что вы соблюдаете передовой опыт. Itech написал сообщение о flake8, в которое включены и другие, если вы хотите узнать больше о линтинге. Линтинг - это не то же самое, что автоматическое форматирование; он показывает только проблемный код в вашем проекте; он не меняет макет вашего кода и не решает эти проблемы за вас. В PyCharm я использую SonarLint, чтобы избавить себя от глупостей.

Интересный факт: Компьютерные экраны из матрицы созданы по рецептам суши.

Расширенные настройки

Недавно коллега познакомил меня с парочкой действительно крутых утилит. Первый из них - пынв. Pyenv позволяет вам управлять несколькими версиями Python на вашем компьютере, не затрагивая системный Python.

Обновление системного Python на машинах * nix считается вредным, поскольку для некоторых встроенных приложений может потребоваться определенная версия Python. Если вы перезапишете это, вы можете сломать вашу систему. Вот почему вам помогает pyenv.

Установка проста, но выходит за рамки этого руководства. Я настоятельно рекомендую вам просмотреть его и попробовать на себе.

Еще один изящный пакет pip, который я использую, называется pipx. pipx позволяет вам устанавливать пакеты python в их виртуальных средах, а затем создает символическую ссылку на /usr/local/bin/, который находится в вашем PATH. Это означает, что вы можете использовать пакеты Python как отдельные приложения (если это имеет смысл) или вы можете взять глобальные пакеты Python, такие как Black, и сделать их общесистемными.

Вы можете установить его, как любой другой пакет pip pip install pipx, и он будет доступен по всему миру. Оттуда вы можете использовать pipx install black для создания виртуальной среды для Black и сделать ее доступной для всей системы.

Файлы требований

Ранее я упоминал pip freeze и файлы требований, а сейчас я хотел бы остановиться на них более подробно.

pip freeze содержит список всех установленных вами пакетов. Он зависит от среды, в которой вы в настоящее время находитесь, будь то системный интерпретатор или виртуальная среда. Когда вы запустите эту команду, вы увидите результат, подобный следующему:

Django==2.2.2
pytz==2019.1
sqlparse==0.3.0

Это результат установки Django 2.2.2. Сначала pip загружает Django, а затем запускает setup.py, о котором мы говорили ранее. Внутри setup.py перечислены две зависимости: pytz и sqlparse. Они могут зависеть от версии и обычно так и есть, поэтому pip устанавливает их вместе с Django. Как только зависимости будут удовлетворены, установка Django завершится, и мы сможем начать новый проект Django.

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

requirements.txt файлы, по соглашению, являются местом, где мы храним требования к пипу проекта. Мы можем передать этот файл в pip с помощью этой команды:

pip install -r requirements.txt

Обратите внимание, что вы должны находиться в том же каталоге, что и файл требований, чтобы указанная выше команда работала как есть. В противном случае вам нужно передать относительный путь к вашему текущему каталогу (т.е. somefolder/requirements.txt).

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

Если вы хотите, чтобы новые установки всегда обновлялись до последней версии, вы можете опустить ==#.#.# в конце.

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

Если вы хотите, чтобы вы всегда получали версию выше определенной, вы можете использовать > или >=.

Наконец, вы можете смешать два, где у вас есть >=0.2,<0.3 в конце, чтобы обозначить больше или равно 0,2 и меньше 0,3. Это означает, что 0.2.1 будет установлен, а 0.25 или 0.3 отклонены.

pip freeze пригодится из-за перенаправления вывода. Вы можете использовать
pip freeze > requirements.txt для отправки вывода в файл с именем requirements.txt. Если файл не существует, он будет создан; в противном случае текст внутри заменяется. Если по какой-то причине вы хотите добавить текст (не рекомендуется), вы можете использовать вместо него >>.

Использование перенаправления вывода экономит много времени, когда дело доходит до создания файлов требований. Мне нравится отделять все свои требования к тестированию от производственных требований. Таким образом, такие пакеты, как pytest или охват, не устанавливаются в производственную среду. Я помещаю все это в test_requirements.txt файл, который устанавливаю на этапах тестирования.

Еще одна вещь, которую я делаю, чтобы очистить файл требований, - это запустить
pip show <package> для каждого пакета, чтобы определить, что требуется для каждого пакета. В выводе pip show Django отображается «Требуется: pytz, sqlparse».

Исходя из этого, я могу удалить как pytz, так и sqlparse из моего файла требований. Вы можете делать это в любом порядке, но я обычно перехожу от основных требований, таких как Django или Flask, к другим, которые, как я знаю, могут потребовать другие пакеты, заканчивая сверху вниз с оставшимися пакетами.

Обратите внимание, что это может вызвать проблемы, если зависимость обновлена, а версия не включена в ваш файл требований, как упомянул Питер в комментариях ниже. См. Его ответ, чтобы узнать, почему.

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

Не волнуйтесь, если вы не знаете, какие из них могут; это приходит со временем и опытом работы с пакетами.

Резюме

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

Ссылки

Если вы хотите узнать больше о создании собственных пакетов или загрузке пакетов в Pypi, ознакомьтесь с руководством пользователя по упаковке Python.



Если вы хотите узнать больше об установке пакетов и виртуальных сред, ознакомьтесь с этим руководством:



Они также есть на docs.python.org.



Что дальше?

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

А пока практикуйте то, что вы узнали!