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

Неудачный эксперимент с аннотациями типа Python

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

Мне нравится Питон, но желаю, чтобы у него было статичное печатать. Добавленная безопасность будет иметь большое значение для улучшения качества и сокращения времени разработки. Итак, сегодня я попытался использовать аннотации типа и статический тип проверки типа Marpy Отказ

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

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

Давайте посмотрим на обе проблемы.

Самообходимость

Я пытаюсь сделать некоторые статьи для Интервью. Коды С моим MDL-процессор Отказ Парсер использует Узел класс для создания дерева разбора. Этот класс содержит Узел Дети как часть древовидной структуры. Логически, это означает, что я бы имел функции, как ниже.

class Node(Object):

    def add_sub( self, sub : Node ):
        ...

    def get_subs( self ) -> Sequence[Node]:
        ...

Marpy У него нет проблем с пониманием этого, но, к сожалению, не допустимый код Python. Вы не можете ссылаться на Узел в пределах Узел класс.

Рабочий обходной путь с использованием Typevar Отказ

NodeT = TypeVar( `NodeT`, bound=`Node` )
class Node(Object):
    def add_sub( self, sub : NodeT ):
        ...

    def get_subs( self ) -> Sequence[NodeT]:
        ...

Это уродливо. Я напомнил о C ++ _t шаблон. Часть моего привлечения к Python является упрощенным синтаксисом. Необходимость украшения классов, как это делает его гораздо менее привлекательным. Кроме того, это код котла, добавляя накладные расходы на более позднее понимание.

Ограничение в Python приходит от Узел еще не быть в таблице символов. Это не делает его в таблицу символов, пока после обработки класса означает, что вы не можете использовать Узел в классе. Это ограничение компилятора. Нет никаких причин, которые это должно быть таким способом, за исключением возможно для обратной совместимости с помощью вводного старого кода.

Возможно, мы не можем использовать имя класса. Но мы могли бы иметь Я или Класс Символ, который относится к приложению класса.

Нет предположенных типов возврата

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

def get_value():
    return 123

Теперь, если вы используете TypectScript или C ++, компилятор может с радостью с удовольствием выводить обратный тип функций. По неизвестным причинам Marpy Choses не делает вывод обратных типов функций. Вместо этого, если нет аннотации типа, он предполагает, что он возвращает тип Любой Отказ

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

Вы дополнительно вынуждены изучать имена и структуру всех типов. Те, которые вы могли бы иным образом игнорировать.

def get_iter():
    return iter(sequence)

def get_closure(self):
    return lamba q : self.op(q)

Почему я должен знать тот тип, что ИТЕР Возвращает, чтобы написать эту функцию? Или у вас есть идеи, какой тип get_cluess возвращается? Я знаю, как использовать возврат, и даже может даже причинять это функцию, но я понятия не имел, как указать свой тип. Знание омриада типов не осуществимо. Вы получите проведение больше времени, пытаясь настроить типы, чем использование кода.

Эта сложность помогла управлять введением Авто ключевое слово в C ++. Существует много ситуаций, когда написание информации о типе не работает. Это особенно верно при работе с параметрическими классами контейнера,

Выводки возврата являются необходимыми функциями.

Избегать этого сейчас

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

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

Образ кредита: Mari Carmen

Оригинал: “https://dev.to/mortoray/a-failed-experiment-with-python-type-annotations-2p40”