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

Аннотации типа Python: лучшие из обоих типов миров

С большой силой приходит большая ответственность Python – это довольно мощный язык с … с меткой Python, Fastapi, WebDev, аннотациями.

Python – это довольно мощный язык с множеством противоречивых особенностей. Одним из них является система печати, я одна из поклонников, поэтому сегодня моя миссия состоит в том, чтобы убедить вас, что это, по крайней мере, неплохо, как утверждают люди. Сегодня мы поговорим о типовых системах и о том, где вписывается Python. Кроме того, вы увидите способ уменьшить нежелательные ошибки и повысить свою кодовую базу с помощью функции аннотаций типа, которая была введена в Python 3.5 ( PEP484 ).

PEP означает предложения по улучшению питона, все предложения и спецификации особенностей Python. Это как ECMA Документы для JavaScript.

Эта функция действительно делает Python лучшим языком динамического типа.

Меньше времени выполнения

Сколько раз вы встречали следующую ошибку:

AttrubtureError: ‘x’ Object не имеет атрибута ‘y’

Это один из самых раздражающих и пробуждающихся ошибок, которые вводит Python. Существует больше ошибок, которые возникают из-за небезопасности с типами переменных и не существующими валидациями типа (или тесты в целом). Как язык динамического типа, все ошибки типа появятся во время выполнения. Попробуйте вспомнить, как разочаровывает его, встречаясь с этим видом исключения в производстве. Для тех из вас, кто знает JavaScript, вы можете увидеть огромную шумиху над TypeScript за последние несколько лет. Почему это? Меньше ошибок! В настоящее время люди понимают, что ошибки в производстве намного хуже всего от добавления типов в своем коде.

Но подождите, давайте вернемся и объясним основы о типовых системах и почему я говорю вещи.

Типовые системы и безопасность аэропорта

Вы прибыли в аэропорт за перелет в ежегодные каникулы. При входе в аэропорт охранник подходит к вам и спрашивает:

Большой парень охраны: «Допустим, у вас есть выбор между 2 вариантами. (1) Прохождение проверки безопасности, которая включает в себя длинные линии и проклятия. (2) Вы свободно идете в свой самолет, и во время полета вас будут проверены. Что бы вы предпочли?”

Эта история выглядит точно так же, как война между динамическими и статическими языками.

Языки статического типа

Ваши типы кода будут проверены в процессе компиляции. Эти типы языков Основные плюсы:

  • Типы безопасности Обнаружение ошибок программирования и избыточных ошибок перед временем выполнения.
  • Документация Лучшая документация для кода.

Если вы знаете о бомбе в вашем аэропорту, вы предпочитаете этот выбор (1).

например: Java, C, C ++

Динамические языки

Ваши типы кода будут проверены только во время выполнения. Эти типы языков Основные плюсы:

  • Читабельно Как правило, быть более читаемыми и естественными. Жить без повторяющихся типов повсюду.
  • Гибкость Гибкость разработки с использованием систем непредсказуемости.
  • Мгновенный Быстрые циклы разработки из -за мгновенного запуска вашего кода (отсутствие проверки, даже на 10 секунд проверка будет накапливаться огромным разочарованием).

Проблема будет, когда на вашем полете будет бомба. Для более безопасного полета (/запуска) ваша кодовая база должна иметь тесты и проверки, которые предотвратят проблемы во время выполнения.

Например: Python, JavaScript, R, Julia

Место Питона Python-это чистый язык динамического типа. Нашей целью будет улучшение недостатков языков динамического типа.

Основная проблема: больше тестов

Мы можем согласиться с тем, что у обоих типов языков кодовые базы должны иметь тесты, но мы живем в несовершенном мире, у нас нет всегда времени для выполнения этих тестов, особенно в крупных кодовых базах, в которых высокий охват трудно нацелить. Динамические языки, как мы уже говорили, менее безопасны в своей сущности. Есть много случаев, которые трудно отслеживать. Распространенным примером является то, что он очень жесткие типы аргументов в глубоких вложенных вызовах функций. Таким образом, чтобы раскрыть ошибки, которые возникают из -за ошибок программиста, должны быть написаны тесты. Как мы можем повысить нашу безопасность, не прилагая никаких усилий и не тратя больше времени?

Лучший из обоих типов миров

Аннотация типа-это просто подтяжки типа, которые могут быть прикреплены к объявлениям переменных и функций. Они могут использоваться сторонними инструментами, такими как контролирование типов, IDES и Linters для предупреждений в режиме реального времени во время кодирования. Время выполнения Python не обеспечивает соблюдение функции и аннотаций типа переменной, поэтому мы на самом деле не делали Python более статичным. Кроме того, интерпретатор Python будет связывать типовые аннотации в качестве комментариев, поэтому никакого влияния на время выполнения. Мы получили статический опыт языка с языком динамического типа.

Давайте представим некоторые центральные особенности типовых аннотаций.

Доступные типы

Встроенные типы Возможно, намекает на каждый из типов встроенных: int, str, float, bool, байты, объект, нет Анкет

Специальные типы

Обратите внимание, что в Python3.9+ большинство из следующих типов изменены и больше не будут импортированы с набор Модуль больше, например, список -> список.

Любой Любой тип возможен. Список [str] Список объектов STR. Тупель [int, int] Суть двух вт. Тупель [int, ...] Кортеж объектов int. Dict [int, int] Дикта с int -ключами к значениям int. Итерабильный [int] Итерабильный, который содержит объекты int. Последовательность [bool] Последовательность логических.

Кстати: последовательность является итерабильной с определенной длиной и дополнительной функциональностью.

Основной пример

def greeting(name: str) -> str:
    return 'Hello ' + name

Если мы запустим следующий код Приветствие (3) Мы получим следующую ошибку:

Ошибка: аргумент 1 к «приветствию» имеет несовместимый тип “int”; Ожидается “Str”

Тип псевдонимов

Можно определить псевдонимы для типов для более читаемого кода.

Url = str

def retry(url: Url, retry_count: int) -> None:
    pass

Дженерики

Typevar – это фабрика, которая может генерировать параметризованные типы. Это может быть очень полезно в классах, которые могут содержать разные типы данных.

from typing import TypeVar, Generic

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self) -> None:
        # Create an empty list with items of type T
        self.items: List[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

    def empty(self) -> bool:
        return not self.items

# Construct an empty Stack[int] instance
stack = Stack[int]()
stack.push(2)
stack.pop()
stack.push('x')        # Type error

Можно создать объект без указания типа, первый объект, который будет вставлен в структуру данных, будет определять параметризованный тип класса (тип inferring).

Гибкость

Иногда вы принимаете несколько типов для своей переменной. Союз Союз [T1, ..., TN] Указав набор возможных типов, каждый из них будет принят.

def f(x: Union[int, str]) -> None:
    if isinstance(x, int):
        x + 1      # OK
    else:
        x + 'a'    # OK

f(1)    # OK
f('x')  # OK
f(1.1)  # Error

Необязательно Необязательно [t] Необязательно будет указано, что переменная содержит указанный тип или Нет Анкет Это на самом деле равно Союз [t, нет] Анкет

def strlen(s: str) -> Optional[int]:
    if not s:
        return None  # OK
    return len(s)

Для много Полезные аннотации Я рекомендую исследовать mypy док.

Зачем использовать типовые аннотации?

IDE – обеспечение соблюдения как компилятор

Лучше, чем компилятор. Вы получили свои потенциальные ошибки во время развития!

Здесь несколько примеров от документов Pycharm до понимания того, как это удивительно. В следующем примере мы видим, что мы выполняем недопустимое задание.

Здесь мы используем Окончательный введите, чтобы отметить переменную как постоянную. Назначение этой константе приведет к ошибке.

Здесь IDE обеспечивает соблюдение значений перечисления для предотвращения любых ошибок программиста, унифицированного формата. Буквальный Тип позволяет предоставлять конкретные примитивные значения для переменной.

Здесь мы используем TypedDict в качестве схемы для аргумента функции.

Эти примеры-падение в океане, я надеюсь, что теперь ясно, как IDE обеспечивает соблюдение ошибок и выступает в качестве исполнителя в реальном времени.

Рефакторинг лучше

Исходя из моего опыта, рефакторирование с помощью типовых подтверждений может сэкономить много времени и нежелательных ошибок в производстве. Во время рефакторинга вы обычно меняете части кода, которые могут повлиять на многие другие места. Как мы уже говорили, для того, чтобы поймать нежелательные ошибки во многих местах, которые нам нужен хороший охват тестов, без него есть хороший потенциал для ошибок программиста, которые не будут обнаружены. Так что, если ваше покрытие не очень хорошее, как вы думаете, аннотации типа помогут.

Тип аннотации в качестве документации

Docstrings обычно являются решением для документации в Python, есть много разных форматов, таких как Epytext, Rest, Google (мой любимый) и многое другое. Нет единого стандартного строгого формата для DocStrings, поэтому в кодовой базе может быть довольно сложно выполнить и проверить проблемы типа.

* Docstrings для людей, типовые аннотации для Линтеров. * Для достижения максимального опыта документации используйте подсказки типа для обеспечения соблюдения любых ошибок и документировать только нетривиальные вещи.

Улучшить предложения IDE

Как мы знаем, иногда наши IDE довольно раздражают. Особенно, когда у вас есть инт переменная и строка предложения сделаны. Типовые аннотации делают предложения более точными и проще. Ввод вашей переменной с помощью определенного типа будет автоматически заполнить вас этими конкретными предложениями типа.

Новые потрясающие инструменты

Типовые аннотации – это не только способ применения типов в вашем коде. Как и каждая функция в Python, можно получить доступ к аннотациям конкретного кода. PEP3107 (Функциональные аннотации) Укажите, как мы можем извлечь метаданные из нашего кода, используя аннотации типа с __annotations__ имущество.

def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
    ...

> foo.__annotations__
{'a': 'x',
 'b': 11,
 'c': list,
 'return': 9}

Почему это хорошо? Для этой функции есть несколько мощных использования, некоторые из них являются картированием запросов базы данных, иностранных мостов, кодировки параметров RPC и проверки схем. Действительно хороший пример использования этой функции – FASTAPI. FASTAPI это быстрая и современная веб -структура, основанная на аннотациях типа Python. Почему это? Почему мы не должны использовать Флару и Джанго и не забыть об этих типах? Ценность . Кроме того, для скорости Fastapi дает несколько мощных функций на основе подсказок типа, например: Openapi Generation Всякий раз, когда вы запускаете свой сервер, файл спецификации OpenAPI (Swagger) будет создан автоматически, вам больше не нужно документировать ваши конечные точки! Схемы и модели данных Другим является модели данных, используя модуль Pydanta, с простыми спецификациями ваших запросов и аргументов отдыха, будет выполнена проверка и преобразование, чтобы вы могли удерживать свои объекты, не возившись в JSONS.

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item

Это также капля в океане. Как бэкэнд -инженер, который работал с несколькими веб -каркасами, я наверняка могу сказать, что эти функции действительно удивительны и мощны.

Mypy

Mypy – это статический тип проверки для Python 2 и 3. Мы можем рассматривать Mypy как наш компилятор, который не выводит ни одного исполняемого файла, только проверяет и находит наши ошибки в базе ввода. Mypy может вводить проверку вашего кода и предотвратить ошибки, она действует как Linter, который работает как статический анализатор. Можно создать файл конфигурации для более оптимизированного и настроенного опыта.

Пример

# main.py
def print_hi(name: str) -> None:  
    print(f'Hi, {name}')  

 > mypy main.py
 > main.py:4: error: Argument 1 to "print_hi" has incompatible type "int"; expected "str"

Mypy и IDE, которые поддерживают аннотации типа являются мощной комбинацией. IDE для предупреждения в режиме реального времени и Mypy для окончательных проверок (возможно в CI).

Вспоминает: Моя цель – убедить ненавистников в том, что эти аннотации типа не плохие, как они утверждают. Типовые аннотации, как и у каждой спорной функции, имеют несколько недостатков. Я расскажу о самых популярных.

Добавление типов в большие кодовые базы без каких -либо подсказок

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

  • Есть несколько инструментов, которые предназначены для решения этой проблемы или, по крайней мере, помощи. MonkeyType и Pyannotate Инструменты могут сделать вывод типов вашего кода во время выполнения Анкет
  • Рекомендуется добавить типовые подсказки в расцвете, выбрать подмножество кода и запустить Mypy в этом подмножестве. Исправить ошибки или игнорировать с помощью # Тип: игнорировать и двигаться дальше. Подмножество подмножества, часть по части. Существует большое преимущество, имея большую кодовую базу с аннотациями типа, рефакторирование будет проще, а ошибки могут быть быстро обнаружены.

Чтобы написать типы, требуется больше времени во время разработки

Хорошо документированный код уже будут иметь типы и документацию, так какова стоимость перемещения типов объявления в аннотацию типа? Если вы не документируете свой код, все же вставьте слово на переменную или объявление метода не кажется очень трудоемким.

Сокращение читаемости

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

Как сказал PEP484:

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

В заключение, аннотация типа может внести большой вклад в ваши кодовые базы. Правила питона.

Оригинал: “https://dev.to/idoazzz/pythons-type-annotations-the-best-of-both-types-worlds-52li”