Глава 16. Создание пакетов библиотек
Вы хотите выпустить скрипт, библиотеку, фреймворк или приложение на Python? Превосходно. Миру нужно больше кода на Python. Python 3 поставляется с системой создания пакетов Distutils. Distutils – это много всего: инструмент сборки (для вас), инструмент установки (для ваших пользователей), формат метаданных пакета (для поисковых систем) и многое другое. Он интегрирован с каталогом пакетов Python PyPI, центральным репозиторием библиотек Python с открытым исходным кодом.
Все эти аспекты Distutils сосредоточены вокруг сценария установки, который обычно называется setup.py . На самом деле, вы уже видели в этой книге несколько скриптов установки Distutils. Вы использовали Distutils для установки httplib2 в HTTP веб-сервисах и еще раз для установки chardet в главе 15 «Учебный пример: портирование chardet на Python 3».
В данной главе вы узнаете, как работают скрипты установки для chardet и httplib2 , и пройдете через процесс релиза своего собственного программного обеспечения на Python.
chardet и httplib2 имеют открытый исходный код, но нет требований, под какой-либо конкретной лицензией вам выпускать собственные библиотеки на Python. Процесс, описанный в данной главе, будет работать для любого программного обеспечения на Python, независимо от лицензии.
16.2 Вещи, которые Distutils не может сделать за вас
Релиз вашего первого пакета Python – сложный процесс (релиз второго немного проще). Distutils пытается максимально автоматизировать его, но есть некоторые вещи, которые вы просто должны сделать сами.
- Выбрать лицензию. Это сложная тема, связанная с политикой и опасностями. Если вы хотите выпустить свое программное обеспечение с открытым исходным кодом, я скромно предлагаю пять советов:
- Не пишите свою собственную лицензию.
- Не пишите свою собственную лицензию.
- Не пишите свою собственную лицензию.
- Это не обязательно должен быть GPL, но она должна быть GPL-совместимой.
- Не пишите свою собственную лицензию.
- Классифицировать свое программное обеспечение, используя систему классификации PyPI. Я объясню, что это значит позже в этой главе.
- Написать файл «прочти меня» (read me). Не экономьте на этом. Как минимум, он должен дать вашим пользователям обзор того, что делает ваше программное обеспечение и как его установить.
16.3 Структура каталогов
Чтобы начать создавать пакет программного обеспечения на Python, вам нужно привести в порядок файлы и каталоги. Каталог httplib2 выглядит так:
- Создайте корневой каталог для хранения всего. Дайте ему то же имя, что и вашему модулю на Python.
- Для удобства пользователей Windows ваш файл «readme» должен иметь расширение .txt и использовать символ возврата каретки. То, что вы используете нестандартный текстовый редактор, который запускается из командной строки и включает в себя собственный язык макросов, не означает, что вам нужно усложнить жизнь своим пользователям (ваши пользователи используют Notepad; грустно но это так). Даже если вы работаете в Linux или Mac OS X, ваш модный текстовый редактор, несомненно, имеет возможность сохранять файлы, используя символы возврата каретки в стиле Windows.
- Ваш скрипт Distutils для установки должен называться setup.py , если у вас нет веских причин так не делать. У вас нет веских причин так не делать.
- Если ваше программное обеспечение на Python представляет собой один файл .py , вы должны поместить его в корневой каталог вместе с файлом «readme» и скриптом установки. Но httplib2 – это не один файл .py; это многофайловый модуль. Но это нормально! Просто поместите каталог httplib2 в корневой каталог, чтобы у вас был файл __init__.py в каталоге httplib2/ в корневом каталоге httplib2/ . Это не проблема; на самом деле это упростит процесс упаковки.
Каталог chardet выглядит немного иначе. Как и httplib2 , это многофайловый модуль, поэтому в корневом каталоге chardet/ находится каталог chardet/ . В дополнение к файлу README.txt , chardet содержит документацию в формате HTML в каталоге docs/ . Каталог docs/ содержит несколько файлов .html и .css и подкаталог images/ , который содержит несколько файлов .png и .gif (это будет важно позднее). Также, в соответствии с соглашением для (L)GPL-лицензированного программного обеспечения, у него есть отдельный файл с именем COPYING.txt , который содержит полный текст LGPL.
16.4 Написание скрипта установки
Скрипт установки Distutils – это скрипт на Python. Теоретически, он может делать всё, что может делать Python. На практике он должен быть как можно меньше, и как можно более стандартным. Скрипты установки должны быть скучными. Чем более экзотичен процесс установки, тем более экзотичны будут ваши сообщения об ошибках.
Первая строка каждого скрипта установки Distutils всегда одинакова:
Это импортирует функцию setup() , которая является основной точкой входа в Distutils. 95% всех скриптов установки Distutils состоят из одного вызова setup() , и ничего более. (Я только что придумал эту статистику, но если ваш скрипт установки Distutils делает больше, чем просто вызывает функцию Distutils setup() , у вас должна быть веская причина. У вас есть веская причина? Не думаю.)
Функция setup() может принимать десятки параметров. Чтобы все вовлеченные участники понимали, о чем идет речь, для каждого параметра вы должны использовать именованные аргументы. Это не просто соглашение; это обязательное требование. Ваш скрипт установки завершится сбоем, если вы попытаетесь вызвать функцию setup() с неименованными аргументами.
Следующие именованные аргументы обязательны:
- name , название пакета;
- version , номер версии пакета;
- author , ваше полное имя;
- author_email , ваш адрес электронной почты;
- url , домашняя страница вашего проекта. Если у вас нет отдельного веб-сайта для проекта, то это может быть ваша страница пакета на PyPI,.
Хотя это и не обязательно, я рекомендую также включить в скрипт установки следующее:
- description , однострочное описание проекта.
- long_description , многострочное описание в формате reStructuredText. PyPI преобразует его в HTML и покажет его на странице вашего пакета.
- classifiers , список специально отформатированных строк, описанных в следующем разделе.
Метаданные скрипта установки определены в PEP 314.
Теперь давайте посмотрим на скрипт установки chardet . В нем есть все эти обязательные и рекомендуемые параметры, плюс один, который я еще не упомянул: packages .
Параметр packages указывает на неудачное совпадение слов в процессе создания дистрибутива. Мы говорим о «пакете» как о том, что вы создаете (и, возможно, включаете его в Python “Package” Index). Но этот параметр packages относится не к этому. Он относится к тому факту, что модуль chardet является многофайловым модулем, иногда называемым… «пакетом». Параметр packages указывает Distutils включить каталог chardet/ , его файл __init__.py и все другие файлы .py , которые составляют модуль chardet . Это очень важно; все эти счастливые разговоры о документации и метаданных не имеют значения, если вы забудете включить реальный код!
16.5 Классификация вашего пакета
Python Package Index (PyPI) содержит тысячи библиотек на Python. Правильные метаданные классификации упростят людям поиск ваших проектов. PyPI позволяет просматривать пакеты по классификатору. Вы даже можете выбрать несколько классификаторов, чтобы сузить область поиска. Классификаторы – это не невидимые метаданные, которые вы можете просто игнорировать!
Чтобы классифицировать ваше программное обеспечение, передайте параметр classifiers функции setup() Distutils. Параметр classifiers представляет собой список строк. Эти строки не являются произвольными. Все строки классификатора должны браться из этого списка на PyPI.
Классификаторы необязательны. Вы можете написать скрипт установки Distutils без каких-либо классификаторов вообще. Но не делайте так. Вы должны всегда включать, по крайней мере, следующие классификаторы:
- Programming Language (язык программирования). В частности, вы должны включить и " Programming Language :: Python ", и " Programming Language :: Python :: 3 ". Если вы не включите их, ваш пакет не будет отображаться в этом списке библиотек, совместимых с Python 3.
- License (лицензия). Это первое, на что я обращаю внимание при оценке сторонних библиотек. Не заставляйте меня охотиться за этой важной информацией. Не включайте более одного классификатора лицензии, если ваше программное обеспечение явно не доступно под несколькими лицензиями. (И не выпускайте программное обеспечение под несколькими лицензиями, если не обязаны это делать. И не заставляйте других людей делать это. Лицензирование – достаточная головная боль; не усугубляйте еще больше.)
- Operating System (операционная система). Если ваше программное обеспечение работает только в Windows (или Mac OS X, или Linux), я хочу узнать об этом раньше, а не позже. Если ваше программное обеспечение работает везде без какого-либо платформозависимого кода, используйте классификатор " Operating System :: OS Independent ". Несколько классификаторов Operating System необходимы только в том случае, если вашему программному обеспечению требуется конкретная поддержка для каждой платформы (это не распространено).
Я также рекомендую вам включить следующие классификаторы:
- Development Status (состояние разработки). Ваше программное обеспечение в версии бета? В версии альфа? Пре-альфа? Выбери один из вариантов. Будьте честны.
- Intended Audience (целевая аудитория). Кто будет загружать ваше программное обеспечение? Наиболее распространенными вариантами являются Developers (разработчики), End Users/Desktop (конечные пользователи / десктоп), Science/Research (наука/исследования) and System Administrators (системные администраторы).
- Framework (фреймворк). Если ваше программное обеспечение является плагином для более крупного фреймворка Python, такого как Django или Zope, включите соответствующий классификатор Framework . Если нет, пропустите его.
- Topic (тема). Есть большое количество тем на выбор; выберите всё, что подходит.
16.5.1 Примеры хороших классификаторов пакетов
В качестве примера, вот классификаторы для Django, готового к работе, кроссплатформенного, лицензированного под BSD фреймворка веб-приложений, который работает на вашем веб-сервере.
Вот классификаторы для chardet , библиотеки определения кодировки символов, описанной в главе 15 «Учебный пример: портирование chardet на Python 3». chardet – в бета-версии, кроссплатформенная, совместимая с Python 3, лицензия LGPL, и предназначена для разработчиков, чтобы интегрировать в свои собственные продукты.
А вот классификаторы для httplib2 , библиотеки, представленной в главе 14 «HTTP веб-сервисы». httplib2 – в бета-версии, кроссплатформенная, с лицензией MIT, предназначена для разработчиков на Python.
16.6 Указание дополнительных файлов с помощью манифеста
По умолчанию Distutils будет включать в ваш пакет следующие файлы:
- README.txt
- setup.py
- Файлы .py , необходимые для многофайловых модулей, перечисленных в параметре packages
- Отдельные .py файлы, перечисленные в параметре py_modules
Это охватывает все файлы в проекте httplib2 . Но для проекта chardet мы также хотим включить файл лицензии COPYING.txt и весь каталог docs/ , содержащий изображения и HTML файлы. Чтобы указать Distutils, чтобы он при сборке пакета chardet включил эти дополнительные файлы и каталоги, вам понадобится файл манифеста.
Файл манифеста – это текстовый файл с именем MANIFEST.in . Поместите его в корневой каталог проекта, рядом с README.txt и setup.py . Файлы манифеста – это не скрипты Python; это текстовые файлы, которые содержат серию «команд» в формате, определенном Distutils. Команды манифеста позволяют включать или исключать определенные файлы и каталоги.
Это весь файл манифеста для проекта chardet :
- Строка 1. Первая строка не требует пояснений: включить файл COPYING.txt из корневого каталога проекта.
- Строка 2. Вторая строка немного сложнее. Команда recursive-include принимает имя каталога и одно или несколько имен файлов. Имена файлов не ограничены конкретными файлами; они могут включать подстановочные знаки. Эта строка означает «Видите этот каталог docs/ в корневом каталоге проекта? Ищите там (рекурсивно) файлы .html , .css , .png и .gif . Я хочу, чтобы все они были в релизе моего пакета.»
Все команды манифеста сохраняют структуру каталогов, заданную вами в каталоге вашего проекта. Эта команда recursive-include не собирается помещать кучу файлов .html и .png в корневой каталог выпускаемого пакета. Она сохранит существующую структуру каталога docs/ , но включая в себя только те файлы в этом каталоге, которые соответствуют заданным подстановочным символам. (Я не упоминал об этом ранее, но документация chardet на самом деле написана в формате XML и преобразована в HTML отдельным скриптом. Я не хочу включать файлы XML в релиз пакета, мне нужны только HTML и изображения.)
Файлы манифеста имеют свой уникальный формат. Для получения подробной информации смотрите определение файлов для распространения и шаблоны команд манифеста.
Повторим: вам нужно создавать файл манифеста, только если вы хотите включить файлы, которые Distutils не включает по умолчанию. Если вам нужен файл манифеста, он должен включать только те файлы и каталоги, которые Distutils не смог бы найти самостоятельно.
16.7 Проверка вашего скрипта установки на наличие ошибок
Есть много чего, что нужно отслеживать. Distutils поставляется со встроенной командой проверки, которая проверяет в вашем скрипте установки наличие всех необходимых метаданных. Например, если вы забудете включить параметр version , Distutils напомнит вам.
После того, как вы добавите параметр version (и все остальные необходимые метаданные), результат команды check будет выглядеть следующим образом:
16.8 Создание дистрибутива исходников
Distutils поддерживает сборку различных типов пакетов. Как минимум, вы должны создать «дистрибутив исходников», который содержит ваш исходный код, ваш скрипт установки Distutils, ваш файл «read me» и все дополнительные файлы, которые вы хотите включить. Чтобы создать дистрибутив исходников, передайте в ваш скрипт установки Distutils команду sdist .
- Distutils заметил файл манифеста ( MANIFEST.in ).
- Distutils успешно проанализировал файл манифеста и добавил нужные нам файлы: COPYING.txt , а также HTML файлы и изображения в каталоге docs/ .
- Если вы загляните в каталог вашего проекта, вы увидите, что Distutils создал каталог dist/ . В этом каталоге dist/ находится .zip -файл, который вы можете распространять.
16.9 Создание графического установщика
По-моему, каждая библиотека Python заслуживает наличие графического установщика для пользователей Windows. Его легко обеспечить (даже если вы сами не работаете под Windows), а пользователи Windows это ценят.
Distutils может создать для вас графический установщик Windows, если передадите в ваш скрипт установки Distutils команду bdist_wininst .
16.9.1 Сборка устанавливаемых пакетов для других операционных систем
Distutils может помочь вам создать устанавливаемые пакеты для пользователей Linux. На мой взгляд, возможно, это не стоит вашего времени. Если вы хотите, чтобы ваше программное обеспечение распространялось для Linux, вам лучше было бы потратить время на работу с членами сообщества, которые специализируются на создании пакетов программного обеспечения для основных дистрибутивов Linux.
Например, моя библиотека chardet находится в репозиториях Debian GNU/Linux (и, следовательно, в репозиториях Ubuntu). Я не имел ничего общего с этим; пакеты просто появились там однажды. Сообщество Debian имеет свои собственные политики для создания пакетов библиотек Python, а пакет Debian python-chardet разработан в соответствии с этими соглашениями. А поскольку пакет находится в репозиториях Debian, пользователи Debian будут получать обновления безопасности и/или новые версии в зависимости от общесистемных настроек, выбранных ими для управления своими компьютерами.
Пакеты Linux, которые собирает Distutils, не предлагают ни одно из этих преимуществ. Лучше потратить время на что-то другое.
16.10 Добавление вашего программного обеспечения в Python Package Index
Загрузка программного обеспечения в Python Package Index состоит из трех этапов.
- зарегистрируетесь сами;
- зарегистрируйте свое программное обеспечение;
- загрузите пакеты, которые вы создали с помощью setup.py sdist и setup.py bdist_ * .
Чтобы зарегистрироваться, перейдите на страницу регистрации пользователя PyPI. Введите имя пользователя и пароль, укажите действующий адрес электронной почты и нажмите кнопку « Create account ». (Если у вас есть ключ PGP или GPG, можете также предоставить его. Если у вас его нет или вы не знаете, что это такое, то не беспокойтесь об этом.) Проверьте свою электронную почту; в течение нескольких минут вы получите сообщение от PyPI со ссылкой для проверки. Нажмите на ссылку, чтобы завершить процесс регистрации.
Теперь вам нужно зарегистрировать свое программное обеспечение в PyPI и загрузить его. Вы можете сделать всё это за один шаг.
- Строка 1. Когда вы публикуете свой проект впервые, Distutils добавит ваше программное обеспечение в Python Package Index и присвоит ему собственный URL. Каждый раз после этого он будет просто обновлять метаданные проекта с любыми изменениями, которые вы могли внести в параметры setup.py . Затем он создает дистрибутив исходного кода ( sdist ) и установщик Windows ( bdist_wininst ), а затем загружает их в PyPI ( upload ).
- Строка 8. Введите 1 или просто нажмите ENTER , чтобы выбрать «использовать существующий логин».
- Строка 9. Введите имя пользователя и пароль, которые вы выбрали на странице регистрации пользователя PyPI. Distuils не будет выводить ваш пароль; он даже не будет отражать звездочки вместо символов. Просто введите свой пароль и нажмите клавишу ENTER .
- Строка 11. Distutils регистрирует ваш пакет в Python Package Index…
- Строка 13. … собирает ваш дистрибутив исходного кода…
- Строка 15. … собирает ваш установщик Windows…
- Строка 17. … и загружает их обоих в Python Package Index.
- Строка 24. Если вы хотите автоматизировать процесс релиза новых версий, то вам нужно сохранить свои учетные данные PyPI в локальном файле. Это совершенно небезопасно и совершенно необязательно.
Поздравляем, теперь у вас есть собственная страница в Python Package Index! Ее адрес: http://pypi.python.org/pypi/NAME , где NAME – это строка, которую вы передали в параметре name в файле setup.py .
Если вы хотите выпустить новую версию, просто обновите в вашем файле setup.py номер версии, а затем снова выполните ту же команду загрузки:
16.11 Множество возможных вариантов создания пакетов Python
Distutils не является единственным инструментом создания пакетов Python, но на момент написания этой статьи (август 2009 года) это единственный фреймворк создания пакетов, который работает в Python 3. Существует ряд других платформ для Python 2; некоторые фокусируются на установке, другие – на тестировании и развертывании. Некоторые или все из них могут в конечном итоге быть перенесены на Python 3 в будущем.
How to create a Python library
Ever wanted to create a Python library, albeit for your team at work or for some open source project online? In this blog you will learn how to!
The tutorial is easiest to follow when you are using the same tools, however it is also possible for you to use different ones.
The tools used in this tutorial are:
— Linux command prompt
— Visual Studio Code
Step 1: Create a directory in which you want to put your library
Open your command prompt and create a folder in which you will create your Python library.
Remember:
— With pwd you can see your present working directory.
— With ls you can list the folders and files in your directory.
— With cd <path> you can change the current present directory you are in.
— With mkdir <folder> you can create a new folder in your working directory.
In my case, the folder I will be working with is mypythonlibrary . Change the present working directory to be your folder.
Step 2: Create a virtual environment for your folder
When starting your project, it is always a good idea to create a virtual environment to encapsulate your project. A virtual environment consists of a certain Python version and some libraries.
Virtual environments prevent the issue of running into dependency issues later on. For example, in older projects you might have worked with older versions of the numpy library. Some old code, that once worked beautifully, might stop working once you update its version. Perhaps parts of numpy are no longer compatible with other parts of your program. Creating virtual environments prevents this. They are also useful in cases when you are collaborating with someone else, and you want to make sure that your application is working on their computer, and vice versa.
(Make sure you changed the present working directory to the folder you are going to create your Python library in ( cd <path/to/folder> ).)
Go ahead and create a virtual environment by typing:
> python3 -m venv venv
Once it is created, you must now activate the environment by using:
> source venv/bin/activate
Activating a virtual environment modifies the PATH and shell variables to point to the specific isolated Python set-up you created. PATH is an environmental variable in Linux and other Unix-like operating systems that tells the shell which directories to search for executable files (i.e., ready-to-run programs) in response to commands issued by a user. The command prompt will change to indicate which virtual environment you are currently in by prepending ( yourenvname ).
In your environment, make sure you have pip installed wheel , setuptools and twine . We will need them for later to build our Python library.
> pip install wheel
> pip install setuptools
> pip install twine
Step 3: Create a folder structure
In Visual Studio Code, open your folder mypythonlibrary (or any name you have given your folder). It should look something like this:
You now can start adding folders and files to your project. You can do this either through the command prompt or in Visual Studio Code itself.
- Create an empty file called setup.py . This is one of the most important files when creating a Python library!
- Create an empty file called README.md . This is the place where you can write markdown to describe the contents of your library for other users.
- Create a folder called mypythonlib , or whatever you want your Python library to be called when you pip install it. (The name should be unique on pip if you want to publish it later.)
- Create an empty file inside mypythonlib that is called __init__.py . Basically, any folder that has an __init__.py file in it, will be included in the library when we build it. Most of the time, you can leave the __init__.py files empty. Upon import, the code within __init__.py gets executed, so it should contain only the minimal amount of code that is needed to be able to run your project. For now, we will leave them as is.
- Also, in the same folder, create a file called myfunctions.py .
- And, finally, create a folder tests in your root folder. Inside, create an empty __init__.py file and an empty test_myfunctions.py .
Your set-up should now look something like this:
Step 4: Create content for your library
To put functions inside your library, you can place them in the myfunctions.py file. For example, copy the haversine function in your file:
This function will give us the distance in meters between two latitude and longitude points.
Whenever you write any code, it is highly encouraged to also write tests for this code. For testing with Python you can use the libraries pytest and pytest-runner . Install the library in your virtual environment:
> pip install pytest==4.4.1
> pip install pytest-runner==4.4
Let’s create a small test for the haversine function. Copy the following and place it inside the test_myfunctions.py file:
Finally, let’s create a setup.py file, that will help us to build the library. A limited version of setup.py will look something like this:
The name variable in setup holds whatever name you want your package wheel file to have. To make it easy, we will gave it the same name as the folder.
Set the packages you would like to create
While in principle you could use find_packages() without any arguments, this can potentially result in unwanted packages to be included. This can happen, for example, if you included an __init__.py in your tests/ directory (which we did). Alternatively, you can also use the exclude argument to explicitly prevent the inclusion of tests in the package, but this is slightly less robust. Let’s change it to the following:
Set the requirements your library needs
Note that pip does not use requirements.yml / requirements.txt when your project is installed as a dependency by others. Generally, for that, you will have to specify dependencies in the install_requires and tests_require arguments in your setup.py file.
Install_requires should be limited to the list of packages that are absolutely needed. This is because you do not want to make users install unnecessary packages. Also note that you do not need to list packages that are part of the standard Python library.
However, since we have only defined the haversine function so far and it only uses the math library (which is always available in Python), we can leave this argument empty.
Maybe you can remember us installing the pytest library before. Of course, you do not want to add pytest to your dependencies in install_requires : it isn’t required by the users of your package. In order to have it installed automatically only when you run tests you can add the following to your setup.py :
Running:
> python setup.py pytest
will execute all tests stored in the ‘tests’ folder.
Step 5: Build your library
Now that all the content is there, we want to build our library. Make sure your present working directory is /path/to/mypythonlibrary (so the root folder of your project). In your command prompt, run:
> python setup.py bdist_wheel
Your wheel file is stored in the “dist” folder that is now created. You can install your library by using:
> pip install /path/to/wheelfile.whl
Note that you could also publish your library to an internal file system on intranet at your workplace, or to the official PyPI repository and install it from there.
Once you have installed your Python library, you can import it using:
import mypythonlib
from mypythonlib import myfunctions
Как написать, упаковать и распространить библиотеку в Python
Python — отличный язык программирования, но упаковка — один из его слабых мест. Это общеизвестный факт в обществе. Установка, импорт, использование и создание пакетов значительно улучшились за эти годы, но это все еще не на одном уровне с новыми языками, такими как Go и Rust, которые многому научились из борьбы Python и других зрелых языков.
В этом руководстве вы узнаете все, что вам нужно знать о написании, упаковке и распространении ваших собственных пакетов.
Как написать библиотеку Python
Библиотека Python — это связная коллекция модулей Python, организованная в виде пакета Python. В общем, это означает, что все модули находятся в одном каталоге и этот каталог находится в пути поиска Python.
Давайте быстро напишем небольшой пакет Python 3 и проиллюстрируем все эти концепции.
Пакет патологии
Python 3 имеет отличный объект Path, который является огромным улучшением по сравнению с неуклюжим модулем Python 2 os.path. Но ему не хватает одной важной возможности — найти путь к текущему сценарию. Это очень важно, когда вы хотите найти файлы доступа относительно текущего скрипта.
Во многих случаях сценарий может быть установлен в любом месте, поэтому вы не можете использовать абсолютные пути, а рабочему каталогу может быть присвоено любое значение, поэтому вы не можете использовать относительный путь. Если вы хотите получить доступ к файлу в подкаталоге или родительском каталоге, вы должны быть в состоянии выяснить текущий каталог скриптов.
Как написать, упаковать и распространять библиотеку на Python
Gigi Sayfan Last updated Aug 1, 2017
Python — отличный язык программирования, но упаковка — одна из его самых слабых точек. Это общеизвестный в сообществе факт. За последние годы установка, импорт, использование и создание пакетов значительно улучшилась, но она все еще не соответствует новым языкам, таким как Go и Rust, которые многому научились в борьбе с Python и другими зрелыми языками.
В этом уроке вы узнаете все, что вам нужно знать о написании, упаковке и распространении собственных пакетов.
Как написать библиотеку Python
Библиотека Python представляет собой согласованный набор модулей Python, который организован как пакет Python. В общем, это означает, что все модули живут под одним и тем же каталогом и этот каталог находится на пути поиска Python.
Давайте быстро напишем небольшой пакет Python 3 и проиллюстрируем все эти понятия.
Пакет Pathology
Python 3 имеет отличный объект Path, который является большим улучшением по сравнению с неудобным модулем Os.path Python 2. Но ему не хватает одной важной возможности — найти путь к текущему сценарию. Это очень важно, если вы хотите найти файлы доступа относительно текущего скрипта.
Во многих случаях сценарий может быть установлен в любом месте, поэтому вы не можете использовать абсолютные пути, а рабочий каталог может быть установлен на любое значение, поэтому вы не можете использовать относительный путь. Если вы хотите получить доступ к файлу в подкаталоге или родительском каталоге, вы должны иметь возможность определить текущий каталог сценариев.
Вот как вы это делаете в Python:
Чтобы получить доступ к файлу с именем ‘file.txt’ в подкаталоге данных в каталоге текущего скрипта, вы можете использовать следующий код:print(open(str(script_dir/’data/file.txt’).read())
С пакетом pathology у вас есть встроенный метод script_dir, и вы используете его следующим образом:
Да, это глоток свежего воздуха. Пакет патологии очень прост. Он выводит свой собственный класс Path из Pathlib Path и добавляет статический script_dir(), который всегда возвращает путь вызывающего скрипта.
Из-за кросс-платформенной реализации pathlib.Path вы можете получить непосредственно от него и должны быть получены из определенного подкласса (PosixPath или WindowsPath). Разрешение dir-файла сценария использует модуль проверки, чтобы найти вызывающего, а затем его атрибут имени файла.
Тестирование пакета патологии
Всякий раз, когда вы пишете нечто более сложное, вы должны его протестировать. Модуль патологии не является исключением. Вот тесты с использованием стандартной модульной тестовой платформы:
Путь Python
Пакеты Python должны быть установлены где-то на пути поиска Python, который должен быть импортирован модулями Python. Путь поиска Python представляет собой список каталогов и всегда доступен в sys.path . Вот мой текущий sys.path:
Обратите внимание, что первая пустая строка вывода представляет текущий каталог, поэтому вы можете импортировать модули из текущего рабочего каталога, что бы это ни было. Вы можете напрямую добавлять или удалять каталоги в / из sys.path.
Вы также можете определить переменную среды PYTHONPATH, и есть несколько других способов ее контролировать. Стандартные site-packages включены по умолчанию, и именно там устанавливаются пакеты, которые вы устанавливаете с помощью pip.
Как упаковать библиотеку Python
Теперь, когда у нас есть наш код и тесты, давайте упакуем все это в нужную библиотеку. Python обеспечивает простой способ через модуль настройки. Вы создаете файл setup.py в корневом каталоге вашего пакета. Затем, чтобы создать исходный дистрибутив, вы запустите: python setup.py sdist
Чтобы создать двоичный дистрибутив, называемый колесом, вы запускаете: python setup.py bdist_wheel
Вот файл setup.py пакета патологии:
Он включает в себя множество метаданных в дополнение к элементу ‘packages’, который использует функцию find_packages() , импортированную из s e tuptools, чтобы найти подпакеты.
Давайте построим дистрибутив источника:
Предупреждение связано с тем, что я использовал нестандартный файл README.md. Это безопасно поэтому игнорируем. Результатом является файл tar-gzipped в каталоге dist:
И вот двоичное распределение:
Пакет патологии содержит только чистые модули Python, поэтому можно создать универсальный пакет. Если ваш пакет включает расширения C, вам нужно будет создать отдельное колесо для каждой платформы:
Для более глубокого погружения в тему упаковки библиотек Python ознакомьтесь, как писать свои собственные пакеты Python.
Как раздавать пакет Python
Python имеет центральный репозиторий пакетов, называемый PyPI (индекс пакетов Python). Когда вы устанавливаете пакет Python с помощью pip, он загружает пакет из PyPI (если вы не укажете другой репозиторий). Чтобы распространять наш пакет патологии, нам нужно загрузить его в PyPI и предоставить некоторые дополнительные метаданные, которые требуется PyPI. Шаги:
- Создайте учетную запись на PyPI (только один раз).
- Зарегистрируйте свой пакет.
- Загрузите свой пакет.
Создайте аккаунт
Вы можете создать учетную запись на веб-сайте PyPI. Затем создайте файл .pypirc в своем домашнем каталоге:
В целях тестирования вы можете добавить «pypitest» индексный сервер в ваш .pypirc файл:
Зарегистрируйте свой пакет
Если это первый выпуск вашего пакета, вам необходимо зарегистрировать его с помощью PyPI. Используйте команду register setup.py. Она попросит вас ввести пароль. Обратите внимание, что я указываю его на тестовый репозиторий:
Загрузите свой пакет
Теперь, когда пакет зарегистрирован, мы можем его загрузить. Я рекомендую использовать twine, который более безопасен. Установите его, как обычно, с помощью pip install twine . Затем загрузите свой пакет с помощью twine и укажите свой пароль (отредактированный ниже):
Для более глубокого погружения в тему распространения ваших пакетов ознакомьтесь с разделом «Пакеты Python».
Заключение
В этом уроке мы прошли полноценный процесс написания библиотеки Python, ее упаковки и распространения через PyPI. На этом этапе у вас должны быть все инструменты для написания и обмена вашими библиотеками с остальным миром.
Кроме того, не стесняйтесь посмотреть, что у нас есть для продажи и для изучения на рынке, и, пожалуйста, задавайте любые вопросы и предоставляйте свою ценную обратную связь, используя приведенный ниже канал.