Oh My Py
2.47K subscribers
21 photos
55 links
Все о чистом коде на Python // antonz.ru
Download Telegram
Вариант «и так сойдёт» не требует дополнительных пояснений :–) А по остальным напишу отдельно.

В комментарии

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

def launch(flyer):
"""Launces a flyer (an object with a `fly()` method)"""
flyer.fly()

Почему бы и нет. Беда в том, что чем сложнее код, тем чаще сбоит «описательный» подход.
🤔2🤯2
Через базовый класс

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

class Flyer:
def fly():
...

class Frank(Flyer):
# ...

class Plane(Flyer):
# ...

class Superman(Flyer):
# ...


def launch(flyer: Flyer):
flyer.fly()


Подход рабочий:

$ mypy flyer.py
Success: no issues found in 1 source file


Но, как говорят авторы Python, ужасно «непитоничный»:

The problem is that a class has to be explicitly marked, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code.

Действительно. Мало того, что нам пришлось модифицировать три класса вместо одной функции. Мало того, что у нас в коде завелась иерархия наследования.

Так еще и Френк, самолет и Супермен теперь объединены общим знанием о том, что они Летающие Объекты. Им прекрасно жилось и без этого, знаете ли.
🤔11👍3
Через протокол

Цитата выше взята из PEP 544 (Python Enhancement Proposal, предложение о доработке), который был реализован в Python 3.8. Начиная с этой версии в питоне появились протоколы.

Протокол описывает поведение без реализации (в других языках такие штуки обычно называют интерфейсами). Вот наш Летающий Объект:

from typing import Protocol

class Flyer(Protocol):
def fly(self):
...


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

def launch(thing: Flyer):
thing.fly()


Причем самим объектам не надо знать о протоколе. Достаточно обладать нужным поведением:

class Frank:
def fly(self):
# ...

class Plane:
def fly(self):
# ...

class Superman:
def fly(self):
# ...


Протокол — это статическая утиная типизация:

— интерфейс явно описан в протоколе: летающий объект обладает методом fly();
— но реализуется он неявно, по «утиному» принципу: у Супермена есть метод fly() — значит он летающий объект.

Проверим:

$ mypy flyer.py
Success: no issues found in 1 source file


Идеально!
👍63🤔4
Многозначительное многоточие

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

class Flyer:
def fly(self):
...


Это вполне рабочий код. В питоне ... (он же Ellipsis) — это реальный объект, который можно использовать в коде.

Ellipsis — единственный экземпляр типа EllipsisType (аналогично тому, как None — единственный экземпляр типа NoneType):

>>> ... is Ellipsis
True
>>> Ellipsis is ...
True


Авторы Python в основном используют ..., чтобы показать, что у типа, метода или функции отсутствует реализация — как в примере с fly().

И в тайп-хинтах:

Tuple[str, ...]
Callable[..., str]


Ну а обычные разработчики... Кто во что горазд ツ

#stdlib
👍21😱7🤯6😁2🔥1🤔1🤩1
Попробуйте Go

Чем больше я узнаю Python, тем больше мне нравится Go.
Альберт Эйнштейн

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

Попробуйте освоить Go в дополнение к Python, если у вас отзывается что-то из перечисленного:

— Хотите поработать с компактным языком без фичеризма и горы легаси.

— Посмотреть, как может выглядеть современная статическая типизация.

— Писать код, который действительно работает быстро (без привычных для питонистов скидок из серии «а мне и так хорошо»).

— Попробовать многозадачность здорового человека.

— Деплоить докер-контейнеры размером в 10 Мб вместо 500 Мб.

Я не думаю, что го обязательно заменит вам питон. Но что может стать отличным инструментом для некоторых задач — уверен.

(минутка саморекламы)

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

Для всех питонистов на этой неделе скидка 50% по промокоду OHMYPY.

Всем Go 🐾
👍43😢6🤩5😁21🤔1
JSON Lines

На днях узнал про формат JSON Lines. Это такой CSV на стероидах:

— каждая запись идет отдельной строкой, как в CSV;
— но при этом представляет собой полноценный JSON.

Например:

{ "id":11, "name":"Дарья" }
{ "id":12, "name":"Борис" }
{ "id":21, "name":"Елена" }


Очень классная штука:

— Подходит для объектов сложной структуры (в отличие от csv);

— Легко потоково читать, не загружая файл целиком в память (в отличие от json);

— Легко дописывать новые записи к существующему файлу (в отличие от json).

JSON, в принципе, тоже можно читать потоково. Но посмотрите, насколько это проще с JSON Lines:

https://replit.com/@antonz/json-lines#main.py
👍38🔥3😁2😢1
ChatGPT-бот на Python

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

В результате появился проект pokitoki — это чат-бот, который работает через официальное API OpenAI.

Чем (на мой глубоко субъективный взгляд) он может вам пригодиться:

— Демонстрирует, как писать несложных телеграм-ботов на питоне.

— Демонстрирует, как интегрироваться с OpenAI.

— Демонстрирует, как запускать питон-приложения в докере.

— Сознательно сделан максимально простым, чтобы можно было быстро разобраться в коде.

Ну и конечно, вы можете подключить его себе в телеграм (если сумеете зарегистрироваться в OpenAI).
🔥37👏64👍4😢1
ChatGPT-бот: группы, внешние ссылки, шорткаты

Сделать GPT-бота легко, а вот удобного GPT-бота — намного сложнее. Последние недели я посвятил именно этому.

Поэтому теперь pokitoki умеет вот что:

— Работает не только в личных чатах, но и в группах.
— Читает внешние ссылки (статьи, код, данные).
— Поддерживает шорткаты (команды для нейросети).
— Экономит время и действия в других частых сценариях.

Код при этом старался сохранять понятным. Есть и комментарии, и тесты.

Подробности на хабре: https://habr.com/ru/post/726692/
🔥24👍137