Рубрики
Без рубрики

Другое преимущество аннотаций типа Python

. Tagged с Python, Typeannotations.

Впервые опубликовано в моем блоге

Исходя из статически напечатанных языков, C и Java, я почувствовал немного небезопасного кода Python. Внезапно, глупые ошибки несоответствия типа, которые я использовал, чтобы поймать во время компиляции, были пойманы только (если вообще, в лучшем случае) во время выполнения. Это стало особенно раздражающим при изучении новых API или погружения в новую большую кодовую базу, и заставило меня полностью полагаться на документацию. Хотя чтение документов важно само по себе, я действительно пропустил комфортное и экономичное завершение кода при печати ». Используя IDE, такие как IntelliJ.

К счастью, со времен Python 3.5, аннотации типов были официально добавлены в Python ( PEP 484 ), и теперь мы можем написать что-то вроде этого:

def hello(name: str) -> None:
    print(f'hello {name}')

Типовые аннотации необязательны

Имея другой синтаксис, чем в C и Java, я нахожу его довольно интуитивно понятным (по крайней мере, простые случаи). Важно отметить, что типовые аннотации полностью необязательны и игнорируются во время выполнения – значение:

  1. Вы не можете нарушить код, добавив его (почти – я уточлюсь в будущей статье)
  2. Они не обеспечивают повышения производительности
  3. Вы можете добавить их только там, где вы считаете нужным-я сделал себе сбалансированное правило всегда аннотирующей функции подписи и переменных модулей, но я обычно не удосужился делать это для локальных переменных

Некоторые преимущества типовых аннотаций

С аннотациями типа в течение довольно долгого времени было написано несколько статей и гидов об их преимуществах, из которых наиболее распространены:

  1. Мы можем использовать Анализ статического кода Чтобы поймать ошибки типа до выполнения времени – Pycharm делает это автоматически, выделяя ошибки типа (хотя, по моему мнению, их легко пропустить). Другой вариант, который определенно рекомендуется,-это полезный инструмент с именем Mypy, который можно запустить в определенных файлах, аннущений для типа, чтобы найти ошибки, связанные с типом (я всегда запускаю его после запуска своих модульных тестов).
  2. Чистый код/код-это самоокументирование – Как пишет дядя Боб в своей (очень рекомендованной) книге «Чистый код»: «Не используйте комментарий, когда вы можете использовать функцию или переменную», мы теперь можем сказать «Не используйте комментарии для указания типа, Когда вы можете использовать аннотацию типа ». Комментарии, как правило, изнашиваются и гниют, в то время как код жив и должен оставаться свежим. Измените типы переменных, не изменяя комментарий с указанием типа – ничего не происходит. Изменить его, не изменяя аннотацию типа? Ваш инструмент статического анализа, в зависимости от того, что это может быть, будет кричать вам. > «Не используйте комментарий, когда вы можете использовать функцию или переменную»

Одним из важных преимуществ, которое, как я вижу, должно наклонить вашу пользу для принятия этой новой функции, если вы до сих пор сопротивлялись, является завершение кода. Раннее согласование ошибок и чистый код очень важны, но я видел, как люди пишут, что более «питоническое» писать утверждения параметров (которые включают проверку типов) в начале функции, или что Docstrings должно быть достаточно. Хотя мы можем спорить об этом, преимущества завершения кода (конечно, при использовании хорошей IDE, такой как Pycharm) являются бесспорными.

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

class Album:
    def __init__(self, title, artist, release_year, tracks):
        self.title = title
        self.artist = artist
        self.release_year = release_year
        self.tracks = tracks

    def all_tracks_shorter_than(self, minutes=0, seconds=0):
        duration = datetime.timedelta(minutes=minutes, seconds=seconds)
        return [t for t in self.tracks if t.duration < duration]


class Track:
    def __init__(self, title, duration):
        self.title = title
        self.duration = duration

Теперь допустим, что я пользователь этой библиотеки, и я хочу распечатать имена всех треков короче 10 минут в желании, что вы были здесь (что я создал ранее):

Подождите минутку, была ли эта переменная, называемая «имя» или «заголовок»? Я этого не знаю! И завершение кода вообще не помогает – я должен перейти к объявлению класса треков или прочитать его документацию – это требует времени! Это лучший сценарий. Это будет стоить еще больше времени, потому что эта ошибка будет найдена только во время выполнения (надеемся, что она использует использует TDD и быстро ее поймает с помощью предварительно написанного теста).

Что произойдет, если мы используем аннотации типа? Давайте добавим только минимальную аннотацию типа, непосредственно необходимую на данный момент:

def all_tracks_shorter_than(self, minutes=0, seconds=0) -> List[Track]:
    duration = datetime.timedelta(minutes=minutes, seconds=seconds)
    return [t for t in self.tracks if t.duration < duration]

Возвращаемое значение этого метода-список треков, поэтому мы добавляем «-> List [Track]» к его подписи (подробнее о синтаксисе аннотаций типа). Посмотрим, что сейчас произойдет при печати ». ‘:

Большой! IDE теперь знает, какой тип эта переменная, и может рекомендовать правильные атрибуты – Ошибка предотвращена! И у пользователей этого пакета будет более дружелюбное время, кодирующее его. Вот как весь класс альбомов выглядит как аннотированный (с моим стилем аннотирования):

class Album:
    def __init__(self, title: str, artist: str, release_year: int, tracks: List[Track]) -> None:
        self.title = title
        self.artist = artist
        self.release_year = release_year
        self.tracks = tracks

    def all_tracks_shorter_than(self, minutes: int = 0, seconds: int = 0) -> List[Track]:
        duration = datetime.timedelta(minutes=minutes, seconds=seconds)
        return [t for t in self.tracks if t.duration < duration]

Завершая, мы видели, что аннотации типа являются отличным дополнением к Python – они улучшают целостность кода Они являются кодом самостоятельного документирования, и они могут повысить производительность клиентов вашего кода.

Дальнейшее чтение:

Оригинал: “https://dev.to/stavshamir/the-other-benefit-of-python-type-annotations-48ib”