Как сделать свой модуль python
Перейти к содержимому

Как сделать свой модуль python

  • автор:

Как выложить свой модуль на PyPI

PyPI (Python Package Index) — это каталог модулей и библиотек для языка программирования Python, которые могут использовать все. Я думаю, все, кто программируют на Python, хотя бы раз устанавливали и использовали модули. Так вот, все пользовательские модули (т. е. те модули, которые вы устанавливаете, а не те, которые идут из-под коробки) выложены на PyPI.

Что нам нужно?

Чтобы выложить свой модуль на PyPI, нам понадобится:

  1. Ваш готовый модуль с правильной структурой файлов (об этом мы поговорим чуть позже).
  2. Аккаунт на PyPI (об этом мы также поговорим позже)
  3. Пакеты setuptools, wheel и twine (их можно установить через pip).
  4. Немного терпения.

Структура проекта

Для дальнейшей работы с модулем нам нужна правильная структура проекта. Вот пример такой структуры:

Структура файлов для модуля

Рассмотрим каждый файл по отдельности:

  • package-root — это корневая папка проекта.
  • package — это папка с исходным кодом модуля.
  • __init__.py — это обязательный файл, в котором должны быть прописаны все нужные вам импорты. Данный файл говорит, что именно эта папка является пакетом.
  • main.py — это просто пример файла, в котором должна быть написана основная логика модуля. Вы можете назвать его по-другому и, если надо, создать ещё сколько угодно файлов.
  • LICENSE — это файл лицензии на ваш проект. Можете использовать любую лицензию, главное, чтобы этот файл содержал текст выбранной вами лицензии.
  • README.md — это файл подробного описания модуля. Рекомендую помещать в него мини-документацию модуля.
  • setup.cfg — это конфигурационный файл для хранения настроек модуля. О том, что в нём писать, поговорим чуть позже.
  • setup.py — это главный установочный файл модуля. За счёт этого файла и будет происходить установка пакета. Что в нём писать, мы также рассмотрим чуть позже.

Регистрация на PyPI

Следующее, что вам нужно сделать — это зарегистрироваться на сайте pypi.org. Об этом я подробно писать не буду, там обычная регистрация.

Файлы setup.py и setup.cfg

Открываем файл setup.py и пишем в нём такой код:

from setuptools import setup, find_packages def readme(): with open('README.md', 'r') as f: return f.read() setup( name='package_name', version='1.0.0', author='your_nickname', author_email='example@gmail.com', description='This is my first module', long_description=readme(), long_description_content_type='text/markdown', url='home_link', packages=find_packages(), install_requires=['requests>=2.25.1'], classifiers=[ 'Programming Language :: Python :: 3.11', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent' ], keywords='example python', project_urls=< 'Documentation': 'link' >, python_requires='>=3.7' )

Давайте подробно рассмотрим написанный выше код. Первая строчка — это импортирование двух функций из библиотеки setuptools, которую вы должны были установить. Функция setup — это функция установки модуля, в которою передаются его параметры. Функция find_packages ищет все пакеты директории. На третьей строчке я написал функцию, которая читает весь текст из файла README.md. Это было сделано для удобства. На седьмой строчке вызываем функцию setup и передаём в неё некоторые параметры. Рассмотрим каждый параметр по отдельности:

  • name — имя пакета.
  • version — версия пакета. Если вы захотите обновить модуль, версия обязательно должна быть другой.
  • author — автор проекта. Можете написать там ваше имя или ваш никнейм (или что захотите).
  • author_email — ваша электронная почта (либо не ваша, как хотите).
  • description — короткое описание пакета.
  • long_description — подробное описание пакета. В данном случае содержимое файла README.md.
  • long_description_content_type — разметка, используемая в подробном описании. Здесь она указана как Markdown.
  • url — ссылка на домашнюю страницу пакета. Чаще всего, пишут ссылку на репозиторий проекта на GitHub.
  • packages — список пакетов, которые должны опубликоваться. Для удобства я использовал функцию find_packages.
  • install_requires — зависимости, которые будут установлены вместе с пакетом.
  • classifiers — метаданные о пакете.
  • keywords — ключевые слова (должны быть указаны через пробел).
  • project_urls — дополнительные ссылки пакета. В данном примере я указал только ссылку на документацию.
  • python_requires — требуемая версия Python.

Теперь открываем файл setup.cfg и пишем туда вот это:

[egg_info] tag_build = tag_date = 0

Так как в моём примере у пакета никаких особых настроек нет, можно задать только вот такие два параметра.

Публикация модуля

Наконец-то мы готовы опубликовать модуль на PyPI. Напомню, что у вас должны быть установлены библиотеки wheel и twine. И так, открываем любую консоль, переходим в корневую директорию проекта и пишем:

python setup.py sdist bdist_wheel

После выполнения данной команды в корневом каталоге должны появится несколько новых папок. Самая главная среди них — это папка dist, в ней находятся дистрибутивные файлы. Для загрузки модуля на test.pypi.org (это тот же PyPI, но для тестовой загрузки модуля, рекомендую сначала загружать туда, а потом на настоящий PyPI) пишем в консоли вот это:

twine upload --repository testpypi dist/*

После введения данной команды в консоли вас попросят ввести имя и пароль с TestPyPI. Если вы правильно ввели ваши данные, через некоторое время модуль будет загружен. А теперь надо выложить модуль на настоящий PyPI. Чтобы это сделать, вводим вот такую команду:

twine upload --repository pypi dist/*

После её введения в консоли вас также должны попросить ввести имя и пароль, но только уже с настоящего PyPI. Если вы всё правильно ввели модуль будет загружен на PyPI.

Вот и всё! Вы выложили свой модуль на PyPI, теперь другие программисты могут его установить и пользоваться им. Спасибо за внимание, мне было приятно поделиться информацией 🙂

№21 Модули Python / Уроки по Python для начинающих

Модуль — это файл, содержащий код python, который вы хотите включить в проект.

Документацию по модулям python на русском мы собрали в разделе Модули.

Создание модуля

Для того, чтобы создать модуль достаточно просто сохранить код в файл с расширением .py :
Сохраним этот код в файл под названием mymodule.py

def greeting(name): print("Привет, " + name) 

Использование модуля

Теперь мы можем использовать только что созданный модуль, с помощью оператора import :

Импортируем модуль под названием mymodule, и вызовем функцию приветствия:

import mymodule mymodule.greeting("Андрей") 
Привет, Андрей 

Примечание: Во время использования функции из модуля, синтаксис: module_name.function_name .

Переменные в модуле

Модуль может содержать функции, как уже описано, но также и переменные всех типов (массивы, словари, объекты и т. д.).
Сохраним этот код в файл mymodule.py

person1 =  "name": "Виктор", "age": 36, "country": "Россия" > 

Импортируем модуль с названием mymodule, и получим доступ к словарю person1 :

import mymodule a = mymodule.person1["age"] print(a) 

Имя модуля

Вы можете назвать файл модуля, как вам нравится, но важно, указать расширение файла .py

Переименование модуля

Вы можете создать псевдоним при импорте модуля, используя ключевое слово as .

import mymodule as mx a = mx.person1["age"] print(a) 

Встроенные модули

В Python есть несколько встроенных модулей, которые вы можете импортировать, когда захотите.

import platform x = platform.system() print(x) 
Windows 

Использование функции dir()

Существует встроенная функция для перечисления всех имен функций (или имен переменных) в модуле. Функция dir() .

import platform x = dir(platform) print(x) 
['DEV_NULL', '_UNIXCONFDIR', '_WIN32_CLIENT_RELEASES', '_WIN32_SERVER_RELEASES', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_default_architecture', '_dist_try_harder', '_follow_symlinks', '_ironpython26_sys_version_parser', '_ironpython_sys_version_parser', '_java_getprop', '_libc_search', '_linux_distribution', '_lsb_release_version', '_mac_ver_xml', '_node', '_norm_version', '_parse_release_file', '_platform', '_platform_cache', '_pypy_sys_version_parser', '_release_filename', '_release_version', '_supported_dists', '_sys_version', '_sys_version_cache', '_sys_version_parser', '_syscmd_file', '_syscmd_uname', '_syscmd_ver', '_uname_cache', '_ver_output', 'architecture', 'collections', 'dist', 'java_ver', 'libc_ver', 'linux_distribution', 'mac_ver', 'machine', 'node', 'os', 'platform', 'popen', 'processor', 'python_branch', 'python_build', 'python_compiler', 'python_implementation', 'python_revision', 'python_version', 'python_version_tuple', 're', 'release', 'subprocess', 'sys', 'system', 'system_alias', 'uname', 'uname_result', 'version', 'warnings', 'win32_ver'] 

Примечание: Функцию dir() можно использовать на всех модулях, включая те, которые вы создаете сами.

Импорт из модуля

Вы можете импортировать модуль только частично, используя ключевое слово from

def greeting(name): print("Привет, " + name) person1 =  "name": "Виктор", "age": 36, "country": "Россия" > 

Импортируем из модуля словарь person1 :

from mymodule import person1 print (person1["age"]) 

Примечание: При импорте с использованием ключевого слова from не используйте имя модуля при обращении к элементам. Пример: person1[«age»] , а не mymodule.person1[«age»]

Модули

Модуль в языке Python представляет отдельный файл с кодом, который можно повторно использовать в других программах.

Для создания модуля необходимо создать собственно файл с расширением *.py , который будет представлять модуль. Название файла будет представлять название модуля. Затем в этом файле надо определить одну или несколько функций.

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

Для этого сначала определим новый модуль: создадим в той же папке, где находится main.py, новый файл, который назовем message.py . По умолчанию интерпретатор Python ищет модули по ряду стандартных путей, один из которых — это папка главного, запускаемого скрипта. Поэтому, чтобы интерпретатор подхватил модуль message.py, для простоты оба файла поместим в один проект.

Модули в Python

Соответственно модуль будет называться message . Определим в нем следующий код:

hello = "Hello all" def print_message(text): print(f"Message: ")

Здесь определена переменная hello и функция print_message, которая в качестве параметра получает некоторый текст и выводит его на консоль.

В основном файле программы — main.py используем данный модуль:

import message # подключаем модуль message # выводим значение переменной hello print(message.hello) # Hello all # обращаемся к функии print_message message.print_message("Hello work") # Message: Hello work

Для использования модуля его надо импортировать с помощью оператора import , после которого указывается имя модуля: import message .

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

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

Например, обращение к функции print_message() из модуля message:

message.print_message("Hello work")

И после этого мы можем запустить главный скрипт main.py, и он задействует модуль message.py. В частности, консольный вывод будет следующим:

Hello all Message: Hello work

Подключение функциональности модуля в глобальное пространство имен

Другой вариант настройки предполагает импорт функциональности модуля в глобальное пространство имен текущего модуля с помощью ключевого слова from :

from message import print_message # обращаемся к функии print_message из модуля message print_message("Hello work") # Message: Hello work # переменная hello из модуля message не доступна, так как она не импортирована # print(message.hello) # print(hello)

В данном случае мы импортируем из модуля message в глобальное пространство имен функцию print_message() . Поэтому мы сможем ее использовать без указания пространства имен модуля как если бы она была определена в этом же файле.

Все остальные функции, переменные из модуля недоступны (как например, в примере выше переменная hello). Если мы хотим их также использовать, то их можно подключить по отдельности:

from message import print_message from message import hello # обращаемся к функции print_message из модуля message print_message("Hello work") # Message: Hello work # обращаемся к переменной hello из модуля message print(hello) # Hello all

Если необходимо импортировать в глобальное пространство имен весь функционал, то вместо названий отдельных функций и переменных можно использовать символ зводочки * :

from message import * # обращаемся к функции print_message из модуля message print_message("Hello work") # Message: Hello work # обращаемся к переменной hello из модуля message print(hello) # Hello all

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

from message import * print_message("Hello work") # Message: Hello work - применяется функция из модуля message def print_message(some_text): print(f"Text: ") print_message("Hello work") # Text: Hello work - применяется функция из текущего файла

Таким образом, одноименная функция текущего файла скрывает функцию из подключенного модуля.

Установка псевдонимов

При импорте модуля и его функциональности мы можем установить для них псевдонимы. Для этого применяется ключевое слово as , после которого указывается псевдоним. Например, установим псевдоним для модуля:

import message as mes # модуль message проецируется на псевдоним mes # выводим значение переменной hello print(mes.hello) # Hello all # обращаемся к функии print_message mes.print_message("Hello work") # Message: Hello work

В данном случае пространство имен будет называться mes , и через этот псевдоним можно обращаться к функциональности модуля.

Подобным образом можно установить псевдонимы для отдельной функциональности модуля:

from message import print_message as display from message import hello as welcome print(welcome) # Hello all - переменная hello из модуля message display("Hello work") # Message: Hello work - функция print_message из модуля message

Здесь для функции print_message из модуля message устанавливается псевдоним display, а для переменной hello — псевдоним welcome. И через эти псевдонимы мы сможем к ним обращаться.

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

from message import print_message as display def print_message(some_text): print(f"Text: ") # функция print_message из модуля message display("Hello work") # Message: Hello work # функция print_message из текущего файла print_message("Hello work") # Text: Hello work

Имя модуля

В примере выше модуль main.py, который является главным, использует модуль message.py. При запуске модуля main.py программа выполнит всю необходимую работу. Однако, если мы запустим отдельно модуль message.py сам по себе, то ничего на консоли не увидим. Ведь модуль message просто определяет функцию и переменную и не выполняет никаких других действий. Но мы можем сделать так, чтобы модуль message.py мог использоваться как сам по себе, так и подключаться в другие модули.

При выполнении модуля среда определяет его имя и присваивает его глобальной переменной __name__ (с обеих сторон по два подчеркивания). Если модуль является запускаемым, то его имя равно __main__ (также по два подчеркивания с каждой стороны). Если модуль используется в другом модуле, то в момент выполнения его имя аналогично названию файла без расширения py. И мы можем это использовать. Так, изменим содержимое файла message.py :

hello = "Hello all" def print_message(text): print(f"Message: ") def main(): print_message(hello) if __name__ == "__main__": main()

В данном случае в модуль message.py для тестирования функциональности модуля добавлена функция main . И мы можем сразу запустить файл message.py отдельно от всех и протестировать код.

Следует обратить внимание на вызов функции main:

if __name__ == "__main__": main()

Переменная __name__ указывает на имя модуля. Для главного модуля, который непосредственно запускается, эта переменная всегда будет иметь значение __main__ вне зависимости от имени файла.

Поэтому, если мы будем запускать скрипт message.py отдельно, сам по себе, то Python присвоит переменной __name__ значение __main__ , далее в выражении if вызовет функцию main из этого же файла.

Однако если мы будем запускать другой скрипт, а этот — message.py — будем подключать в качестве вспомогательного, для message.py переменная __name__ будет иметь значение message . И соответственно метод main в файле message.py не будет работать.

Данный подход с проверкой имени модуля является более рекомендуемым подходом, чем просто вызов метода main.

В файле main.py также можно сделать проверку на то, является ли модуль главным (хотя в прицнипе это необязательно):

import message def main(): message.print_message("Hello work") # Message: Hello work if __name__ == "__main__": main()

Python предоставляет ряд встроенных модулей, которые мы можем использовать в своих программах. В следующих статьях рассмотрим основные из них.

Как написать свой Python-модуль

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

Обложка поста Как написать свой Python-модуль

Написание Python-модуля может быть полезным, когда нужно повторно использовать код в разных проектах или хочется создать библиотеку собственных функций и классов для облегчения разработки. Если вы кодите на Python на повседневной основе и — о чудо! — выделили повторяющийся функционал в отдельный набор функций, классов, методов и переменных, и хотите “стабилизировать” такой код для последующего быстрого подключения, то статья для вас.

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

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

Шаг 1: Создание модуля

Создадим новый файл с именем mymodule.py и откроем его в любимом текстовом редакторе.

Кстати, если вы только начинаете писать код на Python и еще не знаете, в какой программе это делать, то вот моя подборка питонических IDE с хорошим UI / UX.

Здесь вы будете определять функции и классы для вашего модуля mymodule.py.

def greet(name): print("Hello, " + name + "!") class Person: def __init__(self, name): self.name = name def say_hello(self): print("Hello, my name is " + self.name) 

Так мы определяем:

  • функцию greet(), которая принимает аргумент name и выводит приветствие;
  • класс Person, который имеет конструктор __init__() для установки имени;
  • метод say_hello(), который выводит приветствие с использованием имени объекта класса.

Шаг 2: Использование модуля

Теперь модуль можно использовать его в других программах. Создадим новый файл с именем main.py и импортируем mymodule следующим образом:

import mymodule mymodule.greet("Alice") person = mymodule.Person("Bob") person.say_hello() 

Здесь мы используем ключевое слово import и вызываем функцию greet().

API как следующая стадия развития модуля

Если ваш модуль разрастается, становится полноценным проектом и обретает, скажем, динамические данные, то самое время ему стать полноценным API (Application Programming Interface – программный интерфейс приложения). Выражаясь простыми словами, то это следующая стадия развития вашего модуля.

С разработкой полноценных API помогают сервисы вроде swagger.io, который ускоряет подгонку вашего модуля к стандартам RESTful, и создание документации. Но об этом – уже в следующей статье.

Когда в собственном модуле нет необходимости

Написание и поддержка собственного модуля отнимают немалое время, как оказалось. И да, здесь лучше не воевать в одиночку: вместе с затыками бороться всегда проще. Так и хочется посоветовать: избегайте офферов, где у вас не будет команды разработчиков, это существенно замедлит кодинг. Более того, если проект, где пригождается самописный модуль, не столь велик, возможно, в таком апгрейде нет необходимости. Иначе на отладку, вызванную несовместимостью используемых внешних библиотек, вы потратите трудовые ресурсы, которых на такое тратить пока не стоит.

Заключение

Надеюсь, статьей мне удалось показать вам, как пишется элементарный модуль. В моей практике такое пригождалось, когда необходимо обсчитать итоговую эффективность бота с помощью классов “(не)успешный диалог”. Так что веселья ради найти, куда бы прикрутить такую фишку, довольно просто. Потому написание элементарных импортируемых модулей часто входит в обучение основам Python.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *