Создание библиотеки Python: полный гайд
Это моя первая статья на Хабр’е и в ней я вам расскажу о том, как создать свою библиотеку Python и загрузить её на PyPi. Давайте начнём.
Капельку определений
PyPI — каталог программного обеспечения, написанного на языке программирования Python. Фактически это хранилище открытых библиотек для языка Python. Каждый может скачать и использовать библиотеку или создать и загрузить свою. По состоянию на февраль 2020 года содержит более 216 000 пакетов.
Каждый раз, когда вы используете команду pip install вы загружаете модуль с PyPi. Ок, я думаю, что с этим разобрались, идем дальше.
Для чего вам нужна своя библиотека?
- Во-первых, во время создания собственной Python библиотеки вы можете получить опыт, который может пригодится вам в дальнейшем.
- Во-вторых, вы можете поместить в библиотеку только нужные вам функции, которые могут облегчить жизнь вам и возможно другим программистам.
- В-третьих, это весело и интересно.
Что вам нужно для создания библиотеки?
- Код с функциями, которые вы планируете использовать.
- Набор пакетов для создания и публикации (setuptools, wheel и twine).
- Аккаунт PyPI (и его API токен — опционально, но об этом позже).
- Желание и терпение.
Подготовка
Ок, мы разобрались с тем, что нам нужно для создания библиотеки, теперь давайте по порядку, начнём с кода и его грамотного оформления.
Для начала, после того как у вас появилась идея, реализуйте всё в отдельном файле и уже потом разбейте на соответствующую структуру (об этом позже). Для примера я буду использовать код класса быстрого взаимодействия с файлами и библиотеку PyDeepLib (возможно позже я напишу об этом статью). Вы можете установить каждую из библиотек командами pip install PyDeepLib и pip install speedfile соответственно. Проекты так же доступны на GitHub (PyDeepLib, speedfile).
Итак, давайте начнём с установки необходимых нам библиотек. Откройте PyCharm (я рекомендую вам использовать именно его, но если у вас его нет, то можете использовать любой другой редактор кода). Создайте новый проект с виртуальным окружением и установите пакеты о которых говорилось раньше ( setuptools , wheel и twine ), используя команду pip install setuptools wheel twine.
Теперь создадим корневую папку для нашего проекта, а в ней файлы setup.py , setup.cfg и папку с таким же названием как корневая.
Файлы нашего проекта на этом этапе должны выглядеть вот так:

Как вы можете заметить я поместил все модули проекта в папку PyDeepLib, её название обязательно должно совпадать с корневой.
Регистрация на PyPi
Я не очень хочу подробно на этом останавливаться, но я это сделаю:
Для регистрации на PyPi вам нежно перейти на сайт pypi.org и нажать на кнопку зарегистрироваться:

После этого все стандартно:

Имя, почта, username и пароль. Я думаю вы с этим справитесь.
Файлы 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='speedfile', version='0.0.1', author='yarik_g', author_email='example@gmail.com', description='This is the simplest module for quick work with files.', long_description=readme(), long_description_content_type='text/markdown', url='your_url', 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='files speedfiles ', project_urls=< 'GitHub': 'your_github' >, python_requires='>=3.6' )
Итак, сначала мы создаём функцию readme , она нужна для чтения README.md файла (я расскажу как создать его максимально быстро и просто позже). И затем мы вызываем функцию setup , в которую нам надо передать некоторое число параметров, о них поговорим подробнее:
- name — название вашей библиотеки.
- version — версия. Когда будете обновлять библиотеку, версию обязательно надо изменить.
- author — автор проекта
- author_email — электронная почта (желательно та, на которую регистрировали аккаунт на PyPi).
- 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
В нашем случае проект очень простой и не требует никакой дополнительной конфигурации.
Основные файлы
Итак, давайте снова вернёмся к файлам проекта PyDeepLib, и рассмотрим устройство файлов модуля.

В папке с кодом проекта обязательно должен быть файл с названием __init__.py . Система ищет его по умолчанию и в нём обычно просто импортируют остальные модули. Вот пример того, как это может выглядеть:

Как видите в нём почти нет кода, только import’ы, весь остальной код же разбит по отдельным файлам. Это намного удобнее чем держать весь код в одном файле, однако к примеру в проекте speedfile весь код располагался в этом основном файле, но там он был небольшим и запутаться там было сложно:

Я думаю, что это всё что надо знать про разбиение кода на модули.
Создание README файла. Красиво и быстро.
У каждой библиотеки должна быть своя документация или хотя-бы описание. Обычно для этого используют README.md файлы. Логично предположить, что для полноты картины нам тоже следует сделать такой файл для библиотеки. Для создания .md файла мы будем использовать редактор markdown файлов, с говорящим названием MarkDownPad2.
Итак, для начало надо скачать редактор (при желании этот пункт можно пропустить. Вы можете редактировать .md файлы прямо в PyCharm или в любом текстовом редакторе, сохранив файл с соответствующим расширением).
Переходим на сайт markdownpad.com и видим, что существует две версии этого редактора, markdownpad free и markdownpad pro. Для наших задач нам вполне хватит бесплатной версии, поэтому жмём на кнопку скачать:

После этого начнётся загрузка и потом останется только установить редактор. Я думаю что вы с этим справитесь, но если что, то на сайте есть инструкция:

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

Фактически, типичное окно редактора текста/кода, каковым MarkDownPad фактически и является. Дальше принцип простой: просто пишем в файл всё то, что вам необходимо иметь в README файле для вашего проекта и применяете инструменты форматирования, такие как: код, цитата, ссылка, заголовок, список и т.д. Я думаю, что самостоятельно разобраться с markdown разметкой будет не очень сложно, но если что, то вот вам полезная статья с наглядным руководством по markdown.
Для примера я просто дам вам код README.md файла библиотеки speedfile:
# Speed File Library # ## What is this? ## The module allows you to work with files in just one line of code, without the need to manually open and close the file each time ## Quick Guide ## The module is based on the following structure: f = open('data.txt') data = f.readlines() f.close() Which Python provides by standard. ---------- ### Using ### Using the library is as simple and convenient as possible: Let's import it first: First, import everything from the library (use the `from `. ` import *` construct). Examples of all operations: Writing the contents of an entire file to a variable using the `read()` function: temp = File(path='test.txt').read() Writing the contents of an entire file to a variable line by line using the `readlines()` function: temp = File(path='test.txt').readlines() Write only the first line from a file using the `readline()` function: temp = File(path='test.txt').readline() Writing data from a variable to a file using write() (overwriting or creating a file): temp = "Test data" File(path='test.txt', data=temp).write() Adding data from a variable to a file using write() (or creating a file): temp = "Test data" File(path='test.txt', data=temp).add() ---------- ## Developer ## My site: [link](https://y-a-r-i-k.github.io/)
И то, как он выглядит на GitHub:

Я надеюсь, вы здесь разберётесь)).
Публикация пакета
Ок, если вы выполнили все предшествующие шаги, но вы готовы к публикации пакета. Итак, переходим к делу:
Открываем терминал или используем встроенный в PyCharm (или редактор кода, который вы используете). Переходим в корневую директорию проекта и пишем:
python setup.py sdist bdist_wheel
После этого создадутся несколько новых папок. Теперь мы готовы к собственно загрузке модуля на PyPi. Пишем это в терминал:
twine upload --repository pypi dist/*
После этого вас попросят ввести ваш usrename и пароль. И на этом моменте хотелось бы остановиться подробнее. Когда вы будете регистрироваться на PyPi вас скорее всего попросят (в добровольно-принудительном порядке) подключить второй фактор защиты. Если вы это уже сделали, то просто указать username и пароль у вас не получится, это вызовет ошибку.
Как же это решить? Очень просто. Вам нужно получить ваш API токен для PyPi.
- Переходим в настройки учётной записи:

- Крутим вниз до пункта с API-токенами и жмём добавить токен:

- Далее вас попросят назвать токен и выбрать область его действия:

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

Итак, обратно выгрузке проекта: теперь в поле для ввода username вам надо указать __token__ а туда где должен быть пароль — ваш API-токен (рекомендую использовать пункт paste или вставить из контекстного меню, так так Ctrl + V может сработать не корректно). После этого жмём Enter и ждём. После завершения загрузки вам дадут ссылку на страницу с вашей библиотекой.
Страница будет выглядеть стандартно, например вот страница PyDeepLib:

Ну, и на этом всё, поздравляю! Вы создали и загрузили свою первую библиотеку на PyPi.
От автора:
Спасибо, что дочитали статью до конца, надеюсь она была вам полезна и сэкономила вам время. Если хотите повлиять на выход дальнейших статей, то можете подписаться на мой telegram-канал, там в том числе будут опросы касаемо выходов новых статей. Если хотите со мной связаться или предложить тему для статьи — мои контакты есть на сайте.
Ещё раз спасибо, что дочитали до сюда!
И еще несколько полезных библиотек для Python (с примерами)
У python одно из самых крупных комьюнити, это обусловлено тем, что этот язык любят многие за его простоту и универсальность. Очень много энтузиастов, которые создают всё новые и новые библиотеки для облегчения разработки, поэтому среди всего этого разнообразия каждый может подобрать несколько библиотек для себя. На github существует много проектов, которые можно встроить к себе в проект, чтобы оптимизировать, улучшить или просто расширить его функционал.
Хотелось бы рассмотреть несколько интересных на мой взгляд библиотек.
Стилизация print
icecream
Для форматирования вывода существует одна удобная библиотека под названием icecream. Она помогает упростить написание логов или принтов для отладки. Рассмотрим пример её работы:
from icecream import ic text = "Привет" ic(text) >>> ic| text: 'Привет'
Чтобы подключить информацию о том, в каком месте программы происходит вывод, необходимо добавить всего лишь один аргумент в конфигурации модуля:
ic.configureOutput(includeContext=True) from icecream import ic ic.configureOutput(includeContext=True) text = "Привет" ic(text) >>> ic| test_modules.py:5 in - text: 'Привет'
Это помогает более точно понять в каком месте происходит сбой в работе программы:
class A: def changeText(self, text): ic(text) A().changeText("Привет!") >>> ic| test_modules.py:10 in changeText()- text: 'Привет!'
Также можно поменять префикс, который добавляется в начале строки, по дефолту он задан “ic|”. Удобно добавить время для вывода, чтобы видеть в какой момент времени и сколько занимал переход от одного принта к другому.
ic.configureOutput(prefix="PRINT| ") text = "Привет" ic(text) >>> PRINT| test_modules.py:7 in - text: 'Привет' from icecream import ic from datetime import datetime as dt ic.configureOutput(includeContext=True) ic.configureOutput(prefix=lambda : f': ') text = "Привет" ic(text) >>> 22-05-2021 15:58:40:851233: test_modules.py:10 in text: 'Привет'
Если у вас уже имеются расставленные принты в коде, то легко можно переприсвоить print на ic:
print = ic text = "Привет" print(text) >>> 22-05-2021 15:59:54:291440: test_modules.py:8 in text: 'Привет'
Рассмотрим пример вывода более сложных структур, например, словарей:
from icecream import ic ic.configureOutput(includeContext=True) ic.configureOutput(prefix="ВЫВОДИМ СЛОВАРЬ:") print = ic import random as rnd def createRndData(): result = <> namesMale = ["Иван", "Петр", "Александр", "Алексей"] namesFemale = ["Кристина", "Екатерина", "Мария", "Дарья"] hobbies = ["Футбол", "Чтение книг", "Спортивная ходьба", "Стрельба из лука", "Плавание", "Поэзия"] cities = ["Москва", "Владивосток", "Воронеж", "Сочи", "Архангельск", "Анапа", "Мурманск", "Магнитогорск"] for name in namesMale: result[name] = for name in namesFemale: result[name] = print(result) createRndData()
Как видно на скриншоте, то вывод данных в таком формате читать гораздо легче, нежели обычный принт.

Также эта библиотека предоставляет возможность стилизовать вывод в зависимости от предоставляемых данных. Например, если есть необходимость дополнительно оформлять текст ошибки (Exception) или есть желание дополнительно выводить тип данных:
from icecream import ic ic.configureOutput(includeContext=True) def styleOutputVars(obj): if isinstance(obj, Exception): obj = f"Ваш доп текст для ошибки: " elif isinstance(obj, int): if obj > 100: obj = f"Пришло число > 100, непорядок: " return repr(obj) ic.configureOutput(argToStringFunction=styleOutputVars) print = ic try: assert isinstance(1, str), ("Ошибка в сравнении типов") except Exception as e: print(e) print(1000, 1, 2, 3, 4, 200)

colorama
Еще одна полезная библиотека — colorama, она позволит раскрашивать текст в консоли. Её удобно использовать совместно с библиотекой icecream. Рассмотрим пару примеров:
from colorama import Fore, Back, Style from datetime import datetime as dt from icecream import ic ic.configureOutput(includeContext=True) ic.configureOutput(prefix=lambda : f': ') def styleOutputVars(obj): if isinstance(obj, Exception): obj = f"Ваш доп текст для ошибки: " elif isinstance(obj, int): if obj > 100: obj = f"Пришло число > 100, непорядок: " return str(obj) ic.configureOutput(argToStringFunction=styleOutputVars) try: assert isinstance(1, str), ("Ошибка в сравнении типов") except Exception as e: print(Fore.BLACK + Back.YELLOW + ic.format(e) + Style.RESET_ALL) print(ic.format(1000))

Многопоточность (многозадачность)
multitasking
multitasking — очень удобная библиотека, которая позволяет только лишь при помощи обертки одним декоратором создавать асинхронные, неблокирующие методы. Эту библиотеку удобно использовать, когда возникает необходимость вызвать в отдельном потоке какой-либо неблокирующий метод, например, при обращении к БД или при ожидании какого-либо ответа от системы, но при этом не очень хочется городить кучу вызовов потоков и т.д..
Достаточно выполнить простую установку: pip install multitasking и далее оборачивать метод декоратором @task
import multitasking import time import random as rnd multitasking.set_max_threads(10) @multitasking.task def tryToSleep(name): for i in range(5): ts = rnd.randint(2, 6)/2 print(name, i, 'спит:', ts) time.sleep(ts) tryToSleep("Первый") tryToSleep("Второй")

И если удалить @multitasking.task, код выполнится последовательно:

Связь с другими языками
pythonnet
Иногда возникает потребность запустить код, написанный на другом языке, через Python, например, в целях проверки работы какого-либо стороннего модуля или для оптимизации кода. Существует несколько библиотек, позволяющих сделать это, например, pythonnet позволяет запустить некоторую часть кода, написанную на C# в Python (pythonnet позволяет рассматривать множество элементов clr, как модули в python).
Создаем проект библиотеки классов C# в visual studio, создаем в неё нужный класс или методы (в случае примера класс, содержащий метод вычисления дискриминанта), создаем .dll и запускаем через pythonnet (более подробно тут):
// имя проекта MyTestCS namespace MyTestCS < public class MyClassCS < public float discriminant(float a, float b, float c) < return b * b - 4 * a * c; >> >
Обращаемся к C# через Python
import clr import os clr.AddReference(os.getcwd() + "\\MyTestCS.dll") from MyTestCS import MyClassCS mc = MyClassCS() print(mc.discriminant(4, 4, 1)) >>> 0.0 print(mc.discriminant(4, 4, 2)) >>> -16.0 print(mc.discriminant(6, 24, 11)) >>> 312.0
JPype
Для этих же целей существует библиотека, которая позволяет запустить Java код в Python. Эта библиотека называется — JPype. Рассмотрим пример работы библиотеки.
Для начала установим её pip install jpype1, далее создадим Java проект, который в будущем скомпилируем в .jar архив, в проекте необходимо создать пакет, в нём класс и прописать следующий код (код вычисляет объем цилиндра):
package pkg_java; import java.util.*; public class JavaPrime < public static double cylinderVolume(double r, double h)< double pi = 3.141592653589793; return r*r*pi*h; >>
Теперь можно создать .jar решение проекта.
В python коде импортируем библиотеку jpype, запустим JVM и пропишем путь к созданному .jar архиву. Далее по аналогии с pythonnet импортируем необходимые пакеты и классы:
from jpype import * jarpath = "java_is_prime.jar" startJVM(getDefaultJVMPath(), "-ea", "-Djava.class.path=%s" % (jarpath)) pkgJava = JPackage("pkg_java") javaPrimeClass = pkgJava.JavaPrime() print(javaPrimeClass.cylinderVolume(43 ,262.5)) >>> 1524811.264327976 print(javaPrimeClass.cylinderVolume(2 ,5.5352)) >>> 69.55737462460088
Таким образом, pythonnet и jpype — отличные решения для интеграции кода C# и Java в Python проект.
Создание десктопных приложений и UI
EEL
Для работы с созданием графических приложений есть несколько популярных библиотек, в частности встроенный tkinter и Qt. Но когда необходимо сделать красивое, легковесное графическое приложение, то хотелось бы использовать что-то более мощное, например, html+css+js, именно с этим может помочь библиотека EEL. Она позволяет создать десктопное приложение, где в качестве графической оболочки используется html, css и js (можно использовать различные фреймворки), а в качестве языка для написания бэк-части используется Python (подробнее тут).
Приведем простой пример использования библиотеки. Python код:
import eel import random as rnd values = ["Привет", "Привет, мир", "Вывод", "Test EEL"] @eel.expose def testfunc(): global values return rnd.choice(values) eel.init("front") eel.start("index.html")
Title Hello
document.getElementById("click-elem").onclick = async () =>
И сама структура проекта должна выглядеть так:

Можно запустить файл main.py и убедиться, что всё работает:


Анимация математических операций и функций
manim
Для создания различного рода графика существуют популярные библиотеки по типу matplotlib, seaborn (построенный поверх matplotlib и pandas). Но хотел бы отметить библиотеку, позволяющую создавать анимации различных графиков, функций и различного рода пользовательских текстов: Manim.
Всего в несколько строк можно создать красивую анимацию в формате mp4 или .gif для презентации или видео:
from manim import * class PointWithTrace(Scene): def construct(self): path = VMobject() dot = Dot(point=[0,2,0]) path.set_points_as_corners([dot.get_center(), dot.get_center()]) def update_path(path): previous_path = path.copy() previous_path.add_points_as_corners([dot.get_center()]) path.become(previous_path) path.add_updater(update_path) self.add(path, dot) self.play(dot.animate.shift([-1,-2,0])) self.play(dot.animate.shift([2, 1.4, 0])) self.play(dot.animate.shift([-2, 0, 0])) self.play(dot.animate.shift([2, -1.4, 0])) self.play(dot.animate.shift([-1, 2, 0])) tex = Tex(r'$f: A \rightarrow B$', tex_template=TexFontTemplates.french_cursive).scale(2) tex.shift(2*DOWN) self.play(Write(tex)) mtex = MathTex(r'f(x) &= 3x^2 - 5x + 1').scale(2) mtex.shift(3*UP) self.play(Write(mtex))
Также более серьёзный пример работы:
Оценка производительности
pympler
Потребление памяти в Python отдельная проблема, которой можно посвятить много времени, поэтому зачастую приходится следить за тем, чтобы python не сожрал всю оперативку. Для проверки памяти есть замечательный модуль pympler, который поможет не только посмотреть память, занимаемую объектом, но также поможет проследить за памятью, которую занимают отдельные классы или типы данных:
from pympler import asizeof class A(): def __init__(self): self.a = [] self.b = [] mya = A() mya.a = [1,2,3, (6,7), "Hi"] print(asizeof.asized(mya)) >>> size 728, flat 56, refs[0], name '' print(asizeof.asized(mya.a, detail=1).format()) >>> [1, 2, 3, (6, 7), 'Hi'] size=384 flat=104 (6, 7) size=128 flat=64 'Hi' size=56 flat=56 1 size=32 flat=32 2 size=32 flat=32 3 size=32 flat=32
Проследим за изменением памяти, занимаемой классом A:
from pympler import tracker from pympler import classtracker class A(): def __init__(self): self.a = [] self.b = [] def full(self): for i in range(10000): self.a.append(i**100) for i in range(10000): self.b.append() tr = classtracker.ClassTracker() tr.track_class(A) tr.create_snapshot() mya = A() mya.a.extend([1, 2, 3, 4, 5, 6, 7, 8, 9]) mya.full() mya2 = A() mya2.full() tr.create_snapshot() tr.stats.print_summary()

И в целом за памятью, занимаемой различными структурами
tr2 = tracker.SummaryTracker() mya = A() mya.a.extend([1, 2, 3, 4, 5, 6, 7, 8, 9]) mya.full() mya2 = A() mya2.full() tr2.print_diff()

py-spy
Но знать распределение памяти зачастую недостаточно, так как программа может тормозить и не выполнять работу за ожидаемое время. В таком случае необходимо отследить, какие процессы сколько времени занимают.
В таком случае можно воспользоваться библиотекой py-spy, она позволяет без остановки программы проверить, сколько времени какие процессы в ней занимают. Установить библиотеку можно через pip install py-spy. Усложним код предыдущей программы, создадим дополнительный модуль sec.py:
import random as rnd def getRndList(): l = [] for i in range(1, 1000000): l.append(rnd.randint(100,10000)%i) return l
import time from sec import * time.sleep(5) print("start") class A: def __init__(self): self.a = [] self.b = [] self.c = [] def full(self): for i in range(1000000): self.a.append(i**100) for i in range(1000000): self.b.append() mya = A() mya.a.extend([1, 2, 3, 4, 5, 6, 7, 8, 9]) mya.full() mya2 = A() mya2.full() mya2.c = getRndList() mya.c = getRndList()
Теперь через терминал достаточно прописать команду py-spy top — python main.py и вы будете получать информацию о времени работы каждого метода программы:

Обработка языков
pymorphy2
NLP — одна из самых популярных тем в машинном обучении и ИИ на сегодняшний день, поэтому актуальность использования различных библиотек для обработки языков велика как никогда.
PyMorphy2 — это морфологический анализатор, который умеет приводить слова к начальной форме; менять формы слова, а также может предоставить морфологическую информацию о слове.
Плюсы этой библиотеки в том, что она позволяет обрабатывать до нескольких десятков тысяч слов в секунду, занимает мало памяти и основана на словаре opencorpora.
Небольшой пример использования библиотеки:
import pymorphy2 morph = pymorphy2.MorphAnalyzer() info = morph.parse('окна') print('ВСЯ ИНФОРМАЦИЯ О СЛОВЕ:') print(info) info = morph.parse('окна')[0] print('НАЧАЛЬНАЯ ФОРМА:') print(info.normal_form) newinfo = info.inflect() print("СТАВИМ В РОД.ПАДЕЖ, МН.Ч:") print(newinfo) print(newinfo.word) print('ПОЛУЧАЕМ ВСЕ СКЛОНЕНИЯ СЛОВА') print(info.lexeme)
Заключение
Существует огромное количество малоизвестных библиотек, которые могут облегчить жизнь разработчику, поэтому в огромном сообществе python-разработчиков всегда можно найти что-то для своего проекта, что поможет расширить функционал вашего проекта или ускорить работу как самого проекта, так и его разработки.
P.s. тесты проводил на win-10 x64, python: v3.6.6.
Как создать библиотеку на Python: подробное руководство
Python — это мощный и гибкий язык программирования, который позволяет создавать различные приложения и инструменты. Библиотеки являются неотъемлемой частью разработки на Python, и создание собственной библиотеки является важным навыком для любого разработчика.
В этом подробном руководстве для начинающих мы рассмотрим основные шаги создания собственной библиотеки в Python. Мы начнем с объяснения, что такое библиотека и какие преимущества она может предложить. Затем мы рассмотрим различные способы создания библиотеки и лучшие практики для ее разработки и документирования.
Одним из главных преимуществ создания библиотеки является возможность повторного использования кода. Вы можете написать функции и классы, которые выполняют определенные задачи, и использовать их в различных проектах. Это сокращает время разработки и помогает избежать дублирования кода.
Пример:
Предположим, что у вас есть несколько проектов, в которых нужно работать с изображениями. Вы можете создать библиотеку с функциями для загрузки, изменения размера и сохранения изображений. Затем вы сможете использовать эту библиотеку в каждом из своих проектов, вместо того чтобы писать один и тот же код для каждого проекта отдельно.
В данном руководстве мы рассмотрим основные шаги создания библиотеки, включая создание файла с расширением .py, написание функций и классов, установку и использование библиотеки с помощью инструмента pip.
Понимание понятия «библиотека» и её применение
Использование библиотек позволяет разработчикам экономить время и ресурсы, ускоряя процесс разработки и повышая его эффективность. Библиотеки предлагают готовые решения для широкого спектра задач — от работы с базами данных и парсинга веб-страниц до машинного обучения и визуализации данных.
Чтобы использовать библиотеку в Python, разработчику необходимо установить ее с помощью менеджера пакетов, такого как pip. После установки библиотеки можно подключить к своему коду с помощью ключевого слова import .
Преимущества использования библиотек в Python включают:
- Переиспользование кода: Библиотеки предлагают готовые решения для широкого спектра задач, что позволяет не писать код с нуля, а воспользоваться готовыми функциями и классами.
- Увеличение производительности: Библиотеки обычно оптимизированы и написаны на более низком уровне, чем чистый Python код. Это позволяет достичь более высокой скорости работы программы.
- Расширение возможностей: Использование библиотек позволяет добавить в программу новые функции и возможности, которых не было изначально доступно в стандартной библиотеке Python.
Библиотеки в Python — это неотъемлемая часть разработки программного обеспечения. Понимание понятия «библиотека» и ее применение позволяет разработчикам эффективно использовать уже существующие ресурсы и достичь более быстрого и качественного развития своих проектов.
Подготовка к созданию библиотеки на Python
Перед тем, как приступить к созданию библиотеки, необходимо выполнить несколько подготовительных шагов:
- Определить цель библиотеки и ее функционал. Четкое понимание, какие задачи должна решать ваша библиотека, позволит правильно спроектировать ее структуру и функции.
- Изучить существующие аналогичные библиотеки. Перед тем, как начать разработку своей библиотеки, полезно ознакомиться с уже существующими решениями для той же проблемы. Это позволит определить, насколько ваше решение будет уникальным и какие функции уже реализованы в других библиотеках.
- Выбрать уникальное имя для библиотеки. Правильно выбрать имя библиотеки — это важный шаг, который поможет другим разработчикам легко найти и использовать вашу библиотеку.
- Определить структуру проекта. Создание четкой структуры проекта поможет организовать код вашей библиотеки и обеспечить его удобную и понятную структуру для использования.
- Инициализировать новый проект с использованием инструментов управления зависимостями, таких как pip или poetry. Это позволит устанавливать, обновлять и управлять зависимостями вашей библиотеки.
Подготовка перед созданием библиотеки является важным шагом, который поможет вам сосредоточиться на решении задачи и создать качественную и полезную библиотеку на Python.
Создание структуры библиотеки
Для создания библиотеки в Python необходимо определить структуру проекта, чтобы грамотно организовать код и управлять зависимостями. В данном разделе мы рассмотрим основные составляющие структуры библиотеки.
1. Корневая папка: Создайте папку, которая будет являться основным каталогом вашей библиотеки. Дайте ей понятное и уникальное название, которое будет отражать сущность вашей библиотеки.
2. Файл инициализации: В корневой папке создайте файл с именем __init__.py . Этот файл обозначает, что папка является Python-пакетом. Внутри файла можно определить переменные, функции, классы и другие элементы, которые будут доступны после импорта библиотеки.
3. Подпапки: Внутри корневой папки можно создать дополнительные подпапки для организации кода. Например, в папке lib можно разместить модули, а в папке tests — модули для тестирования.
4. Модули: Модуль — это файл с расширением .py , в котором содержится код определенной функциональности. Внутри модуля вы можете определить функции, классы, переменные и другие элементы, которые будут использоваться в библиотеке.
5. Зависимости: Если ваша библиотека зависит от внешних пакетов или модулей, вы можете указать их в файле requirements.txt . Это позволит пользователям легко установить необходимые зависимости при использовании вашей библиотеки.
6. Документация: Чтобы ваша библиотека была понятной и удобной для использования, рекомендуется включить документацию. Создайте файл README.md и запишите в него информацию о библиотеке, ее возможностях, примеры использования и другую полезную информацию.
Организация структуры библиотеки важна для удобства использования и разработки. Следуя этим рекомендациям, вы сможете создать понятную и гибкую библиотеку в Python.
Как создать свой первый open source проект на Python (17 шагов)
Каждый разработчик ПО должен знать как создать библиотеку с нуля. В процессе работы Вы можете многому научиться. Только не забудьте запастись временем и терпением.
Может показаться, что создать библиотеку с открытым исходным кодом сложно, но Вам не нужно быть потрепанным жизнью ветераном своего дела, чтобы разобраться в коде. Также как Вам не нужна мудреная идея продукта. Но точно понадобятся настойчивость и время. Надеюсь, что данное руководство поможет Вам создать первый проект с минимальной затратой и первого, и второго.
В этой статье мы пошагово разберем процесс создания базовой библиотеки на Python. Не забудьте заменить в приведенном ниже коде my_package, my_file и т.п. нужными вам именами.
Шаг 1: Составьте план
Мы планируем создать простую библиотеку для использования в Python. Данная библиотека позволит пользователю легко конвертировать блокнот Jupyter в HTML-файл или Python-скрипт.
Первая итерация нашей библиотеки позволит вызвать функцию, которая выведет определенное сообщение.
Теперь, когда мы уже знаем, что хотим делать, нужно придумать название для библиотеки.
Шаг 2: Дайте имя библиотеке
Придумывать имена сложно. Они должны быть короткими, уникальными и запоминающимися. Также они должны быть написаны строчными буквами, без прочерков и прочих знаков препинания. Подчеркивание не рекомендуется. В процессе создания библиотеки убедитесь, что придуманное Вами имя доступно на GitHub, Google и PyPi.
Если Вы надеетесь и верите, что однажды Ваша библиотека получит 10000 звезд GitHub, то стоит проверить, доступно ли данное имя в социальных сетях. В данном примере я назову свою библиотеку notebookc, потому что это имя доступное, короткое и более-менее описывает суть моей задумки.
Шаг 3. Настройте среду
Убедитесь, что у вас установлены и настроены Python 3.7, GitHub и Homebrew. Если вам нужно что-то из этого, вот подробности:
Python
Скачайте Python 3.7 здесь и установите его.
GitHub
Если у вас нет учетной записи GitHub, перейдите по этой ссылке и оформите бесплатную подписку. Посмотрите, как установить и настроить Git здесь. Вам потребуется утилита командной строки. Перейдите по ссылкам, скачайте и установите все, что Вам понадобится, придумайте юзернейм и укажите электронную почту.
Homebrew
Homebrew — менеджер библиотек для Mac. Инструкции по установке найдете здесь.
Venv
Начиная с Python 3.6 рекомендуется использовать venv для создания виртуальной среды для разработки библиотек. Существует множество способов управления виртуальными средами с помощью Python и все они со временем изменяются. Можете ознакомиться с обсуждением здесь, но, как говорится, доверяй, но проверяй.
Начиная с версии Python 3.3 venv входит в систему по умолчанию. Обратите внимание, что venv устанавливает pip и setuptools начиная с Python 3.4.
Создайте виртуальную среду Python 3.7 с помощью следующей команды:
python3.7 -m venv my_env
Замените my_env вашим именем. Активируйте среду таким образом:
Теперь вы должны наблюдать (my_env) (или имя, которое вы выбрали для вашей виртуальной среды) в крайнем левом углу терминала.
Когда закончите работу, деактивируйте виртуальную среду с помощью deactivate .
Теперь давайте настроим GitHub.
Шаг 4: Создайте организацию в GitHub
GitHub — лидер на рынке реестров контроля версий. Еще две популярные опции — GitLab и Bitbucket. В данном гиде мы будем использовать именно GitHub.
Вам придется часто обращаться к Git и GitHub, поэтому если Вы не знакомы с системой, то можете обратиться к моей статье.
Создайте новую организацию в GitHub. Следуйте инструкциям. Я назвал свою организацию notebooktoall. Вы можете создать репозиторий под своей личной учетной записью, но одна из целей работы — научиться создавать проект с открытым исходным кодом для более широкого сообщества.

Шаг 5: Настройте GitHub Repo
Создайте новый репозиторий. Я назвал свой notebookc.

Добавьте .gitignore из выпадающего списка. Выберите Python для своего репозитория. Содержимое Вашего файла .gitignore будет соответствовать папкам и типам файлов, исключенным из вашего хранилища. Вы можете позже изменить .gitignore, чтобы исключить другие ненужные или конфиденциальные файлы.
Рекомендую выбрать лицензию в списке Выбрать лицензию. Она определяет, что могут делать пользователи Вашего репозитория. Одни лицензии позволяют больше других. Если Вы ничего не выбираете, то автоматически начинают действовать стандартные законы об авторских правах. Узнайте больше о лицензиях здесь.
Для этого проекта я выбрал третью версию Открытого лицензионного соглашения GNU, потому что она популярная, проверенная и “гарантирует пользователям свободу использования, изучения, обмена и изменения программного обеспечения” — источник.

Шаг 6: Клонируйте и добавьте директории
Выберите, куда Вы хотите клонировать Ваш репозиторий или выполните следующую функцию:
git clone https://github.com/notebooktoall/notebookc.git
Подставьте свою организацию и репозиторий.
Перейдите в папку проекта с помощью десктопного графического интерфейса или редактора кода. Или используйте командную строку с cd my-project и после просмотрите файлы с ls —A .
Ваши исходные папки и файлы должны выглядеть так:
.git
.gitignore
LICENSE
README.rst
Создайте вложенную папку для основных файлов проекта. Я советую назвать ее так же, как и вашу библиотеку. Убедитесь, что в имени нет пробелов.
Создайте файл с именем __init__.py в основной вложенной папке. Этот файл пока останется пустым. Он необходим для импорта файлов.
Создайте еще один файл с таким же именем, как у основной вложенной папки, и добавьте .py. Мой файл называется notebookc.py. Вы можете назвать этот Python-файл как захотите. Пользователи библиотеки при импорте модуля будут ссылаться на имя этого файла.
Содержимое моей директории notebookc выглядит следующим образом:
.git
.gitignore
LICENSE
README.rst
notebookc/__init__.py
notebookc/notebookc.py
Шаг 7: Скачайте и установите requirements_dev.txt
На верхнем уровне директории проекта создайте файл requirements_dev.txt. Часто этот файл называют requirements.txt. Назвав его requirements_dev.txt, Вы показываете, что эти библиотеки могут устанавливаться только разработчиками проекта.
В файле укажите, что должны быть установлены pip и wheel.
Обратите внимание, что мы указываем точные версии библиотек с двойными знаками равенства и полными номерами версии.
Закрепите версии вашей библиотеку в requirements_dev.txt
Соавтор, который разветвляет репозиторий проекта и устанавливает закрепленные библиотеки require_dev.txt с помощью pip, будет иметь те же версии библиотеки, что и Вы. Вы знаете, что эта версия будет работать у них. Кроме того, Read The Docs будет использовать этот файл для установки библиотек при сборке документации.
В вашей активированной виртуальной среде установите библиотеку в файл needs_dev.txt с помощью следующей команды:
pip install -r requirements_dev.txt
Настоятельно рекомендую обновлять эти библиотеки по мере выхода новых версий. На данный момент установите любые последние версии, доступные на PyPi.
В следующей статье расскажу, как установить инструмент, облегчающий этот процесс. Подпишитесь, чтобы не пропустить.
Шаг 8: Поработайте с кодом
В целях демонстрации давайте создадим базовую функцию. Свою собственную крутую функцию сможете создать позже.
Вбейте следующее в Ваш основной файл (для меня это notebookc/notebookc/notebookc.py):
def convert(my_name): """ Print a line about converting a notebook. Args: my_name (str): person's name Returns: None """ print(f"I'll convert a notebook for you some day, .")
Вот наша функция во всей красе.
Строки документа начинаются и заканчиваются тремя последовательными двойными кавычками. Они будут использованы в следующей статье для автоматического создания документации.
Сохраните изменения. Если хотите освежить память о работе с Git, то можете заглянуть в эту статью.
Шаг 9: Создайте setup.py
Файл setup.py — это скрипт сборки для вашей библиотеки. Функция setup из Setuptools создаст библиотеку для загрузки в PyPI. Setuptools содержит информацию о вашей библиотеке, номере версии и о том, какие другие библиотеки требуются для пользователей.
Вот мой пример файла setup.py:
from setuptools import setup, find_packages with open("README.md", "r") as readme_file: readme = readme_file.read() requirements = ["ipython>=6", "nbformat>=4", "nbconvert>=5", "requests>=2"] setup( name="notebookc", version="0.0.1", author="Jeff Hale", author_email="jeffmshale@gmail.com", description="A package to convert your Jupyter Notebook", long_description=readme, long_description_content_type="text/markdown", url="https://github.com/your_package/homepage/", packages=find_packages(), install_requires=requirements, classifiers=[ "Programming Language :: Python :: 3.7", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", ], )
Обратите внимание, что long_description установлен на содержимое файла README.md. Список требований (requirements), указанный в setuptools.setup.install_requires, включает в себя все необходимые зависимости для работы вашей библиотеки.
В отличие от списка библиотек, требуемых для разработки в файле require_dev.txt, этот список должен быть максимально разрешающим. Узнайте почему здесь.
Ограничьте список install_requires только тем, что Вам надо — Вам не нужно, чтобы пользователи устанавливали лишние библиотеки. Обратите внимание, что необходимо только перечислить те библиотеки, которые не являются частью стандартной библиотеки Python. У Вашего пользователя и так будет установлен Python, если он будет использовать вашу библиотеку.
Наша библиотека не требует никаких внешних зависимостей, поэтому Вы можете исключить четыре библиотеки, перечисленных в примере выше.
Соавтор, который разветвляет репозиторий проекта и устанавливает закрепленные библиотеки с помощью pip, будет иметь те же версии, что и Вы. Это значит, что они должны работать.
Измените информацию setuptools так, чтобы она соответствовала информации вашей библиотеки. Существует множество других необязательных аргументов и классификаторов ключевых слов — см. перечень здесь. Более подробные руководства по setup.py можно найти здесь и здесь.
Сохраните свой код в локальном репозитории Git. Пора переходить к созданию библиотеки!
Шаг 10: Соберите первую версию
Twine — это набор утилит для безопасной публикации библиотек Python на PyPI. Добавьте библиотеку Twine в следующую пустую строку файла require_dev.txt таким образом:
twine==1.13.0
Затем закрепите Twine в Вашей виртуальной среде, переустановив библиотеки needs_dev.txt.
pip install -r requirements_dev.txt
Затем выполните следующую команду, чтобы создать файлы библиотеки:
python setup.py sdist bdist_wheel
Необходимо создать несколько скрытых папок: dist, build и — в моем случае — notebookc.egg-info. Давайте посмотрим на файлы в папке dist. Файл .whl — это файл Wheel — встроенный дистрибутив. Файл .tar.gz является исходным архивом.
На компьютере пользователя pip будет по мере возможности устанавливать библиотеки как wheels/колеса. Они устанавливаются быстрее. Когда pip не может этого сделать, он возвращается к исходному архиву.
Давайте подготовимся к загрузке нашего колеса и исходного архива.
Шаг 11: Создайте учётную запись TestPyPI
PyPI — каталог библиотек Python (Python Package Index). Это официальный менеджер библиотек Python. Если файлы не установлены локально, pip получает их оттуда.
TestPyPI — это работающая тестовая версия PyPI. Создайте здесь учетную запись TestPyPI и подтвердите адрес электронной почты. Обратите внимание, что у Вас должны быть отдельные пароли для загрузки на тестовый сайт и официальный сайт.
Шаг 12: Опубликуйте библиотеку в PyPI
Используйте Twine для безопасной публикации вашей библиотеки в TestPyPI. Введите следующую команду — никаких изменений не требуется.
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
Вам будет предложено ввести имя пользователя и пароль. Не забывайте, что TestPyPI и PyPI имеют разные пароли!
При необходимости исправьте все ошибки, создайте новый номер версии в файле setup.py и удалите старые артефакты сборки: папки build, dist и egg. Перестройте задачу с помощью python setup.py sdist bdist_wheel и повторно загрузите с помощью Twine. Наличие номеров версий в TestPyPI, которые ничего не значат, особой роли не играют — Вы единственный, кто будет использовать эти версии библиотек.
После того, как Вы успешно загрузили свою библиотеку, давайте удостоверимся, что Вы можете установить его и использовать.
Шаг 13: Проверьте и используйте установленную библиотеку
Создайте еще одну вкладку в командном интерпретаторе и запустите другую виртуальную среду.
python3.7 -m venv my_env
source my_env/bin/activate
Если Вы уже загрузили свою библиотеку на официальный сайт PyPI, то сможете выполнить команду pip install your-package . Мы можем извлечь библиотеку из TestPyPI и установить его с помощью измененной команды.
Вот официальные инструкции по установке вашей библиотеки из TestPyPI:
Вы можете заставить pip загружать библиотеки из TestPyPI вместо PyPI, указав это в index-url.
pip install --index-url https://test.pypi.org/simple/ my_package
Если хотите, чтобы pip также извлекал и другие библиотеки из PyPI, Вы можете добавить — extra-index-url для указания на PyPI. Это полезно, когда тестируемая библиотека имеет зависимости:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple my_package
Если у вашей библиотеки есть зависимости, используйте вторую команду и подставьте имя вашей библиотеки.
Вы должны увидеть последнюю версию библиотеки, установленного в Вашей виртуальной среде.
Чтобы убедиться, что Вы можете использовать свою библиотеку, запустите сеанс IPython в терминале следующим образом:
python
Импортируйте свою функцию и вызовите ее со строковым аргументом. Вот как выглядит мой код:
from notebookc.notebookc import convert
convert(“Jeff”)
После я получаю следующий вывод:
I’ll convert a notebook for you some day, Jeff.
(Когда-нибудь я конвертирую для тебя блокнот, Джефф)
Шаг 14: Залейте код на PyPI
Залейте Ваш код на настоящий сайт PyPI, чтобы люди могли скачать его с помощью pip install my_package .
Загрузить код можно так:
twine upload dist/*
Обратите внимание, что Вам нужно обновить номер версии в setup.py, если Вы хотите залить новую версию в PyPI.
Отлично, теперь давайте загрузим нашу работу на GitHub.
Шаг 15: Залейте библиотеку на GitHub
Убедитесь, что Ваш код сохранен.
Моя папка проекта notebookc выглядит так:
.git .gitignore LICENSE README.md requirements_dev.txt setup.py notebookc/__init__.py notebookc/notebookc.py
Исключите любые виртуальные среды, которые Вы не хотите загружать. Файл Python .gitignore, который мы выбрали при создании репозитория, не должен допускать индексации артефактов сборки. Возможно, Вам придется удалить папки виртуальной среды.
Переместите вашу локальную ветку на GitHub с помощью git push origin my_branch .
Шаг 16: Создайте и объедините PR
В браузере перейдите к GitHub. У Вас должна появиться опция сделать pull-запрос. Нажимайте на зеленые кнопки, чтобы создать, объединить PR и чтобы убрать удаленную ветку.
Вернувшись в терминал, удалите локальную ветку с git branch -d my_feature_branch .
Шаг 17: Обновите рабочую версию на GitHub
Создайте новую версию библиотеки на GitHub, кликнув на релизы на главной странице репозитория. Введите необходимую информацию о релизе и сохраните.
На сегодня достаточно!
Мы научимся добавлять другие файлы и папки в будущих статьях.
А пока давайте повторим шаги, которые мы разобрали.
Итог: 17 шагов к рабочей библиотеке

- Составьте план.
- Дайте имя библиотеке.
- Настройте среду.
- Создайте организацию в GitHub.
- Настройте GitHub Repo.
- Клонируйте и добавьте директории.
- Скачайте и установите requirements_dev.txt.
- Поработайте с кодом.
- Создайте setup.py.
- Соберите первую версию.
- Создайте учётную запись TestPyPI.
- Опубликуйте библиотеку в PyPI.
- Проверьте и используйте установленную библиотеку.
- Залейте код на PyPI.
- Залейте библиотеку на GitHub.
- Создайте и объедините PR.
- Обновите рабочую версию на GitHub.
Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:
- Курс по Machine Learning (12 недель)
- Курс «Профессия Data Scientist» (24 месяца)
- Курс «Профессия Data Analyst» (18 месяцев)
- Курс «Python для веб-разработки» (9 месяцев)
Читать еще
- Крутые Data Scientist не тратят время на статистику
- Как стать Data Scientist без онлайн-курсов
- Шпаргалка по сортировке для Data Science
- Data Science для гуманитариев: что такое «data»
- Data Scienсe на стероидах: знакомство с Decision Intelligence
- учебный процесс
- data science
- data analysis
