Коробка с питоном
538 subscribers
45 photos
119 links
Заметки от Python-разработчика: сниппеты, обзоры пакетов, новости и другая полезная информация.

Автор: @kiriharu
Download Telegram
В канале недавно уже был пост про namedtuple, но мне ещё есть что про него рассказать.

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

>>> lst = ['Mining', 'Excavating', 'Boiling']
>>> Skills = namedtuple('Skills', lst)
>>> skills = Skills(1, 2, 3)
>>> skills
Skills(Mining=1, Excavating=2, Boiling=3)

Ещё мы можем создать кортеж через метод _make():

>>> skills = Skills._make([1, 2, 3])
Skills(Mining=1, Excavating=2, Boiling=3)

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

Именованные кортежи неизменяемые, но мы можем использовать метод _replace(), чтобы изменить данные. Под капотом он использует метод _make для создания нового кортежа, поэтому, по сути, мы просто пересоздадим кортеж:

>>> skills._replace(Mining=100)
Skills(Mining=100, Excavating=2, Boiling=3)
#std
Коробка с питоном
В канале недавно уже был пост про namedtuple, но мне ещё есть что про него рассказать. Первое, что я хотел бы вам показать - именованный кортеж можно создать с помощью любой структуры данных, которая поддерживает итерирование: >>> lst = ['Mining', 'Excavating'…
В комментариях спросили, почему используются методы которые начинаются с нижнего подчеркивания, так как так принято обозначать приватные методы класса (которые не доступны пользователям). Ответ прост - соглашение об именах начинающихся со знака подчёркивания здесь имеет другое значение. Методы с нижним подчеркиванием являются вспомогательными, а проименованы они так чтобы избежать коллизий имён с полями кортежа.
А мы вернемся к нашим методам.

Метод _asdict() создаст словарь из именованного кортежа и вернет его:

>>> skills._asdict()
{'Mining': 1, 'Excavating': 2, 'Boiling': 3}

Ещё один полезный метод - _fields(). Он вернет кортеж из полей. Очень полезно, если вы хотите создать ещё один именованный кортеж:

>>> AllSkills = namedtuple('AllSkills', Skills._fields + ('Taming', 'Woodcutting'))
>>> AllSkills._fields
('Mining', 'Excavating', 'Boiling', 'Taming', 'Woodcutting')
Типизация именованных кортежей.

Один из комментаторов указал, что namedtuple() объявлен устаревшим и в 3.10 его поддержка прекратится. Что же делать? Использовать NamedTuple, если в вашем проекте питон выше версии 3.6.

Именованный кортеж можно создать 2 путями - через наследование NamedTuple (класс Skills) или старым способом (AnotherSkills). Оба способа содержат аннотации типов, повышающие (как минимум) читаемость кода.
Все методы, которые были в namedtuple (_make(), _replace(), _asdict()) работают:

>>> s = Skills(0)
>>> s._asdict()
{'mining': 0, 'excavating': 1}

Теперь мы можем посмотреть на аннотации:

s.__annotations__
{'mining': <class 'int'>, 'excavating': <class 'int'>}

Так же, ничего не мешает добавлять новые методы или оверрайтить существующие. В примере у Skills переопределен метод для str():

>>>str(s)
'Какой качок, уровень копания: 0\nуровень лесорубства: 100'

GitHub
#std
Про применение all()

Стандартная библиотека Python полна полезных вещей, но полезные вещи есть даже среди встроенных функций. Одна из таких встроенных функций - это all().

Функция all() возвращает True, если все элементы истинные (или объект пустой).

К примеру, all() очень удобно использовать с генераторами. Например, мы можем проверить, являются ли все октеты в IP-адресе числами:

>>> all(i.isdigit() for i in '127.0.0.b'.split('.'))
False
>>> all(i.isdigit() for i in '127.0.0.1'.split('.'))
True
#std
orjson - самая быстрая библиотека для (де)сериализации json, написанная на Rust.

Умеет нативно сериализовать объекты из dataclass, datetime, numpy и UUID. Имеет множество опций для тонкой настройки парсера, содержит вещи которых нет в парсере стандартной библиотеки. Имеет более полное соответствие UTF-8 и JSON формату.

PyPi | GitHub | Бенчмарки
#библиотека
Поиск N максимальных или минимальных элементов.

Если вы хотите создать список из N максимальных или минимальных элементов, модуль heapq вам поможет в этом.
У этого модуля есть две функции: nlargest() и nsmallest(), которые, соответственно ищут максимальные и минимальные элементы. Например:

>>> nums = [10, 20, 30, 40, 55, 632, -3, 98321, 82, 0, 8]
>>> heapq.nlargest(4, nums)
[98321, 632, 82, 55]
>>> heapq.nsmallest(4, nums)
[-3, 0, 8, 10]

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

currency = [
dict(name="Etherium", price=3323),
dict(name="Bitcoin", price=45538),
dict(name="ZCash", price=132),
dict(name="Litecoin", price=184),
dict(name="OmiseGo", price=8.933)
]

>>> heapq.nsmallest(2, currency, key=lambda s: s['price'])
[{'name': 'OmiseGo', 'price': 8.933}, {'name': 'ZCash', 'price': 132}]
>>> heapq.nlargest(2, currency, key=lambda s: s['price'])
[{'name': 'Bitcoin', 'price': 45538}, {'name': 'Etherium', 'price': 3323}]
#std
Определяем наиболее часто встречающиеся элементы в последовательности.

Допустим, у нас есть некоторая последовательность из слов (words), и мы хотим узнать, какие элементы в ней встречаются чаще остальных.

Для этого можно использовать класс Counter из модуля collections в котором есть метод most_common(), который и выдаст список элементов, которые встречаются чаще остальных.

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

>>>counts['test']
2

Кстати, эта задача часто встречается на собеседованиях и просят её реализовать без модуля collections. Как бы вы её решили? Ответы можете писать в комментарии, обсудим.
#std
Коробка с питоном pinned «В прошлом месяце было не так много постов, как хотелось бы, но всё же... Итоги сентября! 🗒 Заметки: - Ещё раз вернемся к namedtuple - Про методы с нижним подчеркиваниям в namedtuple - Типизация именованных кортежей (NamedTuple) - Про применение all() - Поиск…»
anytree - простая и расширяемая структура представляющая дерево.

Умеет:

- Экспорт в текст как на картинке/картинку с различными вариантами рендера
- Импорт/Экспорт json/dict/yaml
- Поиск, обход, кеширование результатов

GitHub | Docs | PyPi
#библиотека
Небольшой хинт про использование Poetry в Docker - зависимости можно экспортировать в обычный requirements.txt, таким образом избегая установки и обновления poetry.

Если вам необходимо просто установить зависимости - экспортируйте их в requirements.txt. А дальше ставьте их как обычно, через pip.

#poetry #docker
Коробка с питоном
Небольшой хинт про использование Poetry в Docker - зависимости можно экспортировать в обычный requirements.txt, таким образом избегая установки и обновления poetry. Если вам необходимо просто установить зависимости - экспортируйте их в requirements.txt. А…
Костылерование и велосипедостроение продолжается 🗿!

Делаю бота в телеге, решил при помощи Github Actions прогонять тесты в докере и дальше деплоить. Менеджмент зависимостей через poetry.
Из-за того что poetry ставит кучу ненужных мне вещей, хочется экспортить мои зависимости в requirements.txt. Первой идеей был git hook, но у нас тут Github Actions есть, давайте генерировать при помощи него 🗿

Результатом стал вот такой workflow. Оно ставит Ubuntu 20.04, Python 3.9 и Poetry 1.1.7. После чего экспортит зависимости и пушит их вам в репозиторий.

Зачем я это сделал? Не понятно, интерес иногда делает веселые вещи.
#github #poetry
Ручной проход по списку

Задачка: нужно пройти по списку не используя цикл for.

Решение у этой задачи достаточно простое - можно использовать функцию next() и ловить исключение StopIteration. На скриншоте можно увидеть пример с использованием цикла while.

Здесь мы получаем итератор - это такой объект, который облегчает навигацию по коллекциям. Дальше в цикле вызываем next(), который получает следующий элемент и так до тех пор пока элементы не закончатся - индикатором этого будет вызов исключения StopIteration.
#std
aiomisc - огромное количество различных утилит для asyncio.

Из самых полезных утилит для себя выделил возможность создавать энтрипоинты с логгированием, огромное количество классов-сервисов (PeriodicService, CronService и т.д.), работа с потоками и управление сигналами.

GitHub | Документация
#библиотека #asyncio
Предложение выпилить GIL продолжают активно обсуждать.

На ежегодный Python core development sprint пригласили Sam Gross (автор nogil), и задавали ему много разных вопросов. Все под впечатлением. Всерьёз обсуждается вливание этого экспериментального форка в основной код CPython, но спешить с этим точно не будут, потому что изменения такого масштаба в интерпретаторе потребуют адаптации многих библиотек и пользовательского кода.

Изменение крупное, но если его добавлять небольшими кусками и растянуть этот процесс на несколько лет, то получится избежать Python 4. А Python 4 никто не хочет.

Сэма пригласили присоединиться к числу core-разработчиков интерпретатора. Łukasz Langa будет его менторить.

Пока что всё выглядит очень оптимистично. Ждите Python 3.20 без GIL 😅

https://lukasz.langa.pl/5d044f91-49c1-4170-aed1-62b6763e6ad0/

#gil
Коробка с питоном pinned «Итоги октября! 🗒 Заметки: - Про Poetry в Docker - Генерация requirements.txt через Poetry в Github Actions - Ручной проход по списку 📚Библиотеки: - anytree - aiomisc»
What the f*ck Python - репозиторий на Github, в котором собраны некоторые интересные примеры с объяснениями, почему происходят те или иные вещи в Python.

#ссылочки
Ormar - очень интересная и небольшая асинхронная ORM, которая поддерживает Postgres, MySQL и SQLite. Построена на базе Pydantic и SQLAlchemy.

Суть проекта - создать легкую ORM, которая могла бы использоваться напрямую (в цикле запрос-ответ) с FastAPI или другими фреимворками.
На данный момент по моему мнению выглядит неплохо, идеологически это достойная замена для WIP SQLModel.

Github | Документация
#библиотека
Если вы пишите на Django или собираетесь писать на нём, я нашёл довольно адекватный и хороший стаилгайд от HackSoftware, который позволит вашему коду на Django не превратиться в макароны.

Стаилгайд описывает большинство кейсов, с которыми сталкивается разработчик - от взаимодействия с моделями и сервисами, до тестирования и работы с Celery.

#ссылочки #django
Давным давно я писал обертку для сервиса, которая генерирует текст-рыбу. Она нужна была чтобы заполнять поля с контентом.

Совсем недавно я начал писать свой проект и углубился в тестирование. Одним из результатов моего поиска ресурсов по этой теме стала библиотека Faker.

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

Github | Документация

#тестирование #библиотека