Основные библиотеки Python, которых вам не хватает

Известно, что Python поставляется с «батарейками в комплекте» благодаря его очень обширной стандартной библиотеке, которая включает в себя множество модулей и функций, которых вы не ожидаете. Тем не менее, есть ещё много полезных библиотек, о которых вы должны знать и которые вы должны использовать во всех своих проектах Python, и вот их список.
Утилиты общего назначения
Мы начнём с пары библиотек общего назначения, которые вы можете использовать во многих проектах. Первая описана в документах как:
«Boltons — это набор утилит на чистом Python в том же духе, что и в стандартной библиотеке, но явно отсутствующий в ней».
Нам понадобилась бы целая статья, чтобы рассмотреть каждую функцию и особенность boltons, но вот пара примеров удобных функций:
# pip install boltons
from boltons import jsonutils, timeutils, iterutils
from datetime import date
# {"name": "John", "id": 1, "active": true}
# {"name": "Ben", "id": 2, "active": false}
# {"name": "Mary", "id": 3, "active": true}
with open('input.jsonl') as f:
for line in jsonutils.JSONLIterator(f): # Automatically converted to dict
print(f"User: {line['name']} with ID {line['id']} is {'active' if line['active'] else 'inactive'}")
# User: John with ID 1 is active
# ...
start_date = date(year=2023, month=4, day=9)
end_date = date(year=2023, month=4, day=30)
for day in timeutils.daterange(start_date, end_date, step=(0, 0, 2)):
print(repr(day))
# datetime.date(2023, 4, 9)
# datetime.date(2023, 4, 11)
# datetime.date(2023, 4, 13)
data = {"deeply": {"nested": {"python": {"dict": "value"}}}}
iterutils.get_path(data, ("deeply", "nested", "python"))
# {'dict': 'value'}
data = {"id": "234411",
"node1": {"id": 1234, "value": "some data"},
"node2": {"id": "2352345",
"node3": {"id": "123422", "value": "more data"}
}
}
iterutils.remap(data, lambda p, k, v: (k, int(v)) if k == 'id' else (k, v))
Хотя стандартная библиотека Python имеет модуль json, она не поддерживает формат JSON Lines (.jsonl). В первом примере показано, как вы можете обрабатывать jsonl с помощью библиотеки boltons.
Второй пример демонстрирует модуль boltons.timeutils, который позволяет создавать диапазоны дат. Вы можете перебрать их и установить аргумент step, например, получать через день. Опять же, это то, чего не хватает в модуле Python datetime.
Наконец, в третьем примере мы используем функцию remap из модуля boltons.iterutils для рекурсивного преобразования всех полей id словаря в целые числа. Здесь boltons.iterutils служит хорошим расширением для встроенного itertools.
Говоря о iterutils и itertools, следующая отличная библиотека, которую вам нужно проверить, это more-itertools , которая предоставляет гораздо больше itertools.
Последней в этой категории является библиотека sh, которая является заменой модуля subprocess. Будет здорово, если вы обнаружите, что в Python вы управляете множеством других процессов:
# https://pypi.org/project/sh/
# pip install sh
import sh
# Run any command in $PATH...
print(sh.ls('-la'))
# total 36
# drwxrwxr-x 2 martin martin 4096 apr 8 14:18 .
# drwxrwxr-x 41 martin martin 20480 apr 7 15:23 ..
# -rw-rw-r-- 1 martin martin 30 apr 8 14:18 examples.py
with sh.contrib.sudo:
# Do stuff using 'sudo'...
...
# Write to a file:
sh.ifconfig(_out='/tmp/interfaces')
# Piping:
print(sh.wc('-l', _in=sh.ls('.', '-1')))
# Same as 'ls -1 | wc -l'
Когда мы вызываем sh.some_command, библиотека sh пытается найти встроенную команду shell или двоичный файл $PATH с таким именем. Если она найдёт такую команду, она просто выполнит её для вас.
Если вам нужно использовать sudo, вы можете использовать контекстный менеджер sudo из модуля contrib, как показано во второй части фрагмента.
Чтобы записать вывод команды в файл, вам нужно только указать аргумент _out. И, наконец, вы также можете использовать каналы ( |) с помощью аргумента _in.
Валидация данных
Ещё одна недостающая часть в стандартной библиотеке Python — это категория инструментов проверки данных. Одна небольшая библиотека, обеспечивающая это, называется validators. Эта библиотека позволяет вам проверять общие шаблоны, такие как электронные письма, IP-адреса или кредитные карты:
# https://python-validators.github.io/validators/
# pip install validators
import validators
validators.email('someone@example.com') # True
validators.card.visa('...')
validators.ip_address.ipv4('1.2.3.456') # ValidationFailure(func=ipv4, args={'value': '1.2.3.456'})
Далее идёт нечёткое сравнение строк — difflib, но этот модуль нуждается в некоторых улучшениях. Некоторые из них можно найти в библиотеке thefuzz (ранее известной как fuzzywuzzy):
# pip install thefuzz
from thefuzz import fuzz
from thefuzz import process
print(fuzz.ratio("Some text for testing", "text for some testing")) # 76
print(fuzz.token_sort_ratio("Some text for testing", "text for some testing")) # 100
print(fuzz.token_sort_ratio("Some text for testing", "some testing text for some text testing")) # 70
print(fuzz.token_set_ratio("Some text for testing", "some testing text for some text testing")) # 100
songs = [
'01 Radiohead - OK Computer - Airbag.mp3',
'02 Radiohead - OK Computer - Paranoid Android.mp3',
'04 Radiohead - OK Computer - Exit Music (For a Film).mp3',
'06 Radiohead - OK Computer - Karma Police.mp3',
'10 Radiohead - OK Computer - No Surprises.mp3',
'11 Radiohead - OK Computer - Lucky.mp3',
'02 Radiohead - Pablo Honey - Creep.mp3',
'04 Radiohead - Pablo Honey - Stop Whispering.mp3',
'06 Radiohead - Pablo Honey - Anyone Can Play Guitar.mp3',
"10 Radiohead - Pablo Honey - I Can't.mp3",
'13 Radiohead - Pablo Honey - Creep (Radio Edit).mp3',
# ...
]
print(process.extract("Radiohead - No Surprises", songs, limit=1, scorer=fuzz.token_sort_ratio))
# [('10 Radiohead - OK Computer - No Surprises.mp3', 70)]
Привлекательность библиотеки thefuzz заключается в функциях *ratio, которые, вероятно, будут работать лучше, чем встроенные difflib.get_close_matches или difflib.SequenceMatcher.ratio. Фрагмент выше показывает их различное использование. Во-первых, мы используем базовый ratio, который вычисляет простую оценку сходства двух строк. После этого мы используем token_sort_ratiowhich, игнорируя порядок токенов (слов) в строке при вычислении сходства. Наконец, мы тестируем функцию token_set_ratio, которая вместо этого игнорирует повторяющиеся токены.
Мы также используем функцию extract из модуля process, которая является альтернативой difflib.get_close_matches. Эта функция ищет наилучшее совпадение в списке строк.
Если вы уже используете difflib и думаете, стоит ли вам использовать thefuzz вместо этого, то обязательно ознакомьтесь со статьей автора библиотеки, в которой хорошо показано, почему встроенных функций difflib не всегда достаточно и почему приведённые выше функции могут работать лучше.
Отладка
Довольно много библиотек отладки и устранения неполадок также обеспечивают превосходные возможности по сравнению со стандартными библиотеками. Одной из таких библиотек является stackprinter, которая предоставляет более полезные версии встроенных сообщений об исключениях Python:
# pip install stackprinter
import stackprinter
stackprinter.set_excepthook(style='darkbg2')
def do_stuff():
some_var = "data"
raise ValueError("Some error message")
do_stuff()
Всё, что вам нужно сделать, чтобы использовать её, это импортировать её и установить ловушку исключения. Затем запуск кода, выдающего исключение, приведёт к следующему:

Это большое улучшение, потому что оно показывает локальные переменные и контекст — то, для чего вам понадобится интерактивный отладчик. Ознакомьтесь с документацией , чтобы узнать о дополнительных параметрах, таких как интеграция с логированием или различные цветовые темы.
stackprinter помогает с отладкой проблем, которые приводят к исключениям, но это лишь небольшая часть проблем, которые мы все отлаживаем. В большинстве случаев поиск и устранение ошибок включает в себя просто размещение операторов printor logпо всему коду, чтобы увидеть текущее состояние переменных или был ли запущен код. И есть библиотека, которая может улучшить отладку print в базовом стиле:
# pip install icecream
from icecream import ic
def do_stuff():
some_var = "data"
some_list = [1, 2, 3, 4]
ic()
return some_var
ic(do_stuff())
# ic| examples.py:46 in do_stuff() at 11:27:44.604
# ic| do_stuff(): 'data'
Она называется icecream и предоставляет функцию ic, которая служит заменой print. Вы можете использовать простой код ic()(без аргументов), чтобы проверить, какие части кода были выполнены. В качестве альтернативы вы можете использовать ic(some_func(...)), которая будет выводить функцию/выражение вместе с возвращаемым значением.
Дополнительные параметры и настройки см. в GitHub README .
Тестирование
Говоря об отладке, мы также должны упомянуть тестирование. Я не собираюсь советовать вам использовать другие тестовые фреймворки вместо встроенных unittest (даже если они просто лучше), вместо этого я хочу показать вам три небольших полезных инструмента:
Первая — это библиотека freezegun, которая позволяет вам тестировать datetime:
# pip install pytest freezegun
from freezegun import freeze_time
import datetime
# Run 'pytest' in shell
@freeze_time("2022-04-09")
def test_datetime():
assert datetime.datetime.now() == datetime.datetime(2022, 4, 9) # Passes!
def test_with():
with freeze_time("Apr 9th, 2022"):
assert datetime.datetime.now() == datetime.datetime(2022, 4, 9) # Passes!
@freeze_time("Apr 9th, 2022", tick=True)
def test_time_ticking():
assert datetime.datetime.now() > datetime.datetime(2022, 4, 9) # Passes!
Всё, что вам нужно сделать, это добавить декоратор к функции test, которая устанавливает дату (или datetime). Кроме того, вы также можете использовать её в качестве диспетчера контекста ( оператор with).
Выше вы также можете увидеть, что она позволяет указать дату в удобном формате. И, наконец, вы также можете передать tick=True, что перезапустит время с заданного значения.
При желании, если вы используете pytest, вы также можете установить pytest-freezegun для фикстур в стиле Pytest.
Второй важной библиотекой/помощником для тестирования, который вам нужен, является dirty-equals. Она предоставляет вспомогательные функции равенства для сравнения вещей, которые вроде как равны:
# pip install dirty-equals
from dirty_equals import IsApprox, IsNow, IsJson, IsPositiveInt, IsPartialDict, IsList, AnyThing
from datetime import datetime
assert 1.0 == IsApprox(1)
assert 123 == IsApprox(120, delta=4) # close enough...
now = datetime.now()
assert now == IsNow # just about...
assert '{"a": 1, "b": 2}' == IsJson
assert '{"a": 1}' == IsJson(a=IsPositiveInt)
assert {'a': 1, 'b': 2, 'c': 3} == IsPartialDict(a=1, b=2) # Validate only subset of keys/values
assert [1, 2, 3] == IsList(1, AnyThing, 3)
Выше приведён пример помощников, которые проверяют, являются ли два целых числа или datetimes примерно одинаковыми; является ли что-то допустимым JSON, включая тестирование отдельных ключей в этом JSON, или является ли значение словарём или списком с определёнными ключами/значениями.
И, наконец, третья полезная библиотека называется pyperclip. Она предоставляет функции для копирования и вставки в/из буфера обмена. Я нахожу это очень полезным для отладки, например, для копирования значений переменных или сообщений об ошибках в буфер обмена, но у этого может быть много других вариантов использования:
# pip install pyperclip
# sudo apt-get install xclip
import pyperclip
try:
print("Do something that throws error...")
raise SyntaxError("Something went wrong...")
except Exception as e:
pyperclip.copy(str(e))
# CTRL+V -> Something went wrong...
В этом фрагменте мы используем автоматическое копирование сообщения об исключении в буфер обмена pyperclip.copy, чтобы нам не приходилось копировать его вручную из результата программы.
CLI
Последняя категория, заслуживающая упоминания, — инструменты CLI. Если вы создаёте приложения CLI на Python, вы можете найти хорошее применение tqdm. Эта небольшая библиотека предоставляет индикатор выполнения для ваших программ:
# pip install tqdm
from tqdm import tqdm, trange
from random import randint
from time import sleep
for i in tqdm(range(100)):
sleep(0.05) # 50ms per iteration
# 0% | | 0/100 [00:00<?, ?it/s]
# 100%|██████████| 100/100 [00:05<00:00, 19.95it/s]
with trange(100) as t:
for i in t:
t.set_description('Step %i' % i)
t.set_postfix(throughput=f"{randint(100, 999)/100.00}Mb/s", task=i)
sleep(0.05)
# Step 60: 60%|██████ | 60/100 [00:03<00:02, 19.78it/s, task=60, throughput=4.06Mb/s]
Чтобы использовать её, мы заключаем цикл в tqdm и получаем индикатор выполнения в выводе программы. В более сложных случаях вы можете использовать диспетчер контекста trange и установить дополнительные параметры, такие как описание или любые настраиваемые поля индикатора выполнения, такие как пропускная способность или истёкшее время.
Модуль также может быть запущен как команда оболочки ( python -m tqdm), что может быть полезно, например, при создании резервной копии tar или поиске файлов с расширением find.
Дополнительные примеры и такие моменты, как интеграция с Pandas или Jupyter Notebook, см. в документации .
Заключение
С Python вы всегда должны искать существующие библиотеки, прежде чем внедрять что-либо с нуля. Если вы не создаёте особенно необычное или индивидуальное решение, скорее всего, кто-то уже создал его и выложил в PyPI.
В этой статье я перечислил только библиотеки общего назначения, которыми может воспользоваться каждый, но есть и много других специализированных, например, для машинного обучения или веб-разработки. Я бы порекомендовал вам заглянуть на https://github.com/vinta/awesome-python , где есть обширный список интересных библиотек, или вы также можете просто поискать PyPI по категориям , и я уверен, что вы найдёте там что-то полезное!



