type hints python что это

Подсказки типов и строки документации Python

В этой статье вы будете сопровождать меня в путешествии по автоматической генерации строк документации в стиле Google из подсказок типов Python. Мы рассмотрим следующие элементы.

Подсказки типа Python

Начиная с Python 3.5+, мы увидели следующее поколение документации по коду: намеки на типы переменных в аргументах функций/классов и операторах возврата. Это позволяет программам форматирования, линтерам и IDE обеспечивать поддержку проверки типов во время выполнения.

Зачем нужны подсказки

Проще говоря, типовые подсказки улучшают документацию исходного кода и читаемость. Они являются частью Python Enhancement Protocols (PEP), эволюционной структуры для повышения ясности и логики кода Python.

Как использовать подсказки типа

Проверка типов

Вставить подсказки типа в строки документации функции

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

Абстрактные синтаксические деревья (AST)

Печать

Метод get_type_hints() из модуля typing возвращает словарь, содержащий подсказки типа для функции, метода, модуля или объекта класса. get_type_hints не работает со строками, поэтому мы используем библиотеку ast для анализа методов из модуля.

Регулярные выражения

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

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

Автоматизация с помощью хуков Git перед фиксацией

Сделав еще один шаг, мы можем автоматически создавать красивую документацию в MkDocs со всеми функциями в наших скриптах Python.

Источник

Введение в аннотации типов Python

Введение


Автор иллюстрации — Magdalena Tomczyk

Python — язык с динамической типизацией и позволяет нам довольно вольно оперировать переменными разных типов. Однако при написании кода мы так или иначе предполагаем переменные каких типов будут использоваться (это может быть вызвано ограничением алгоритма или бизнес логики). И для корректной работы программы нам важно как можно раньше найти ошибки, связанные с передачей данных неверного типа.

Сохраняя идею динамической утиной типизации в современных версиях Python (3.6+) поддерживает аннотации типов переменных, полей класса, аргументов и возвращаемых значений функций:

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

Меня зовут Тихонов Андрей и я занимаюсь backend-разработкой в Lamoda.

Инструменты, поддерживающие аннотации

Аннотации типов поддерживаются многими IDE для Python, которые выделяют некорректный код или выдают подсказки в процессе набора текста.

Например, так это выглядит в Pycharm:

Так же аннотации типов обрабатываются и консольными линтерами.

А вот для того же файла что нашел mypy:

Поведение разных анализаторов может отличаться. Например, mypy и pycharm по разному обрабатывают смену типа переменной. Далее в примерах я буду ориентироваться на вывод mypy.

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

Основы

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

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

Аннотации для переменных пишут через двоеточие после идентификатора. После этого может идти инициализация значения. Например,

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

Кстати, при использовании dataclass типы полей необходимо указывать именно в классе. Подробнее про dataclass

Встроенные типы

Optional

Incompatible types in assignment (expression has type «None», variable has type «int»)

Для таких случаев предусмотрена в модуле typing аннотация Optional с указанием конкретного типа. Обратите внимание, тип опциональной переменной указывается в квадратных скобках

Union

Для случаев, когда необходимо допустить использование не любых типов, а только некоторых, можно использовать аннотацию typing.Union с указанием списка типов в квадратных скобках.

Коллекции

Механизм аннотаций типов поддерживает механизм дженериков (Generics, подробнее во второй части статьи), которые позволяют специфицировать для контейнеров типы элементов, хранящихся в них.

Списки

Кортежи

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

Словари

Аналогично используются typing.DefaultDict и typing.OrderedDict

Результат выполнения функции

Для указания типа результата функции можно использовать любую аннотацию. Но есть несколько особенных случаев.

Если же функция никогда не возвращает управление (например, как sys.exit ), следует использовать аннотацию NoReturn :

Вместо заключения

Так же стандарт определяет формат аннотаций в виде комментариев и stub-файлы, которые содержат информацию только для статических анализаторов.

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

Источник

Аннотации типов в Python

Введение

Примеры

Общие типы

T = typing.TypeVar («T»)

Добавление типов в функцию

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

а также с другими значениями, например, list с, tuple ов и так далее.

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

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

Аннотации следовать имя аргумента и отделены друг от друга : характер.

Хотя подсказки типов в основном используются средствами проверки типов и средами разработки, иногда вам может потребоваться получить их. Это может быть сделано с помощью __annotations__ специального атрибута:

Члены класса и методы

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

Переменные и атрибуты

Переменные комментируются с помощью комментариев:

В отличие от комментариев, также можно просто добавить подсказку типа в переменную, которая не была ранее объявлена, без установки значения:

NamedTuple

Создание namedtuple с намеками типа осуществляется с помощью функции NamedTuple из typing модуля:

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

Введите подсказки для аргументов ключевых слов

Обратите внимание на пробелы вокруг знака равенства, в отличие от того, как обычно вводятся ключевые аргументы.

Читайте также:  какие страны могут объединиться в будущем

Синтаксис

Параметры

Примечания

Научим основам Python и Data Science на практике

Это не обычный теоритический курс, а онлайн-тренажер, с практикой на примерах рабочих задач, в котором вы можете учиться в любое удобное время 24/7. Вы получите реальный опыт, разрабатывая качественный код и анализируя реальные данные.

Модуль dis

Введение Примеры Константы в модуле dis EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands HAVE_ARGUMENT = 90 # All opcodes greater than this have at least 1 operands cmp_op =

Стеки в Python

Источник

Русские Блоги

Полностью понять подсказки типов в Python (Type Hints)

Как все мы знаем, Python является динамически типизированным языком, и тип переменной не нужно указывать во время выполнения. Это не изменится, но в сентябре 2015 года основатель Гвидо ван Россум представил систему типов в Python 3.5, которая позволяет разработчикам указывать типы переменных. Его основная функция заключается в облегчении разработки, используемой IDE и различными инструментами разработки, и не влияет на выполнение кода, а также будет фильтровать информацию о типах во время выполнения.

Одним из главных преимуществ Python является то, что он динамически набирается, и это не изменится. И в сентябре 2014 годаGuido van Rossum (Python BDFL) Создано предложение по улучшению Python (PEP-484), Добавить подсказки типа (Type Hints) для Python. И через год он был выпущен как часть Python 3.5.0 в сентябре 2015 года. Так дляДвадцать пять летPython, есть стандартный способ добавить информацию о типе в код. В этой записи блога я расскажу о том, как развивается система, как мы ее используем и каков следующий шаг для подсказки типов.

Зачем вам нужны подсказки типа?

Преимущества подсказок типа

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

Легко понять код

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

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

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

Просто глядя на сигнатуру этой функции, мы можем узнать:

Фактически, многие из нас уже понимают, что предоставление информации о типе в коде крайне важно. Однако из-за отсутствия лучших опций информация о типе в коде часто упоминается в документации.

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

lint относится к инструментам статического анализа кода

Легко рефакторинг

Тип подсказка может помочь нам найти класс лучше при рефакторинге.

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

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

Простая в использовании библиотека

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

Type Linters

Хотя среда IDE предупреждает о неправильных типах параметров, целесообразно использовать инструмент linter для расширения этой функции, чтобы обеспечить логический тип приложения. Такие инструменты могут помочь вам обнаружить ошибки как можно раньше (например, пример после ввода должен иметь тип str, а передача None вызовет исключение):

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

Проверьте рабочие данные

Подсказки типа могут использоваться для проверки во время выполнения, чтобы гарантировать, что вызывающая сторона не нарушает соглашения метода. Больше нет необходимости использовать длинный список утверждений типа в начале функции, вместо этого мы можем использовать платформу, которая повторно использует подсказки типов и автоматически проверяет, удовлетворяются ли они до запуска бизнес-логики (например, используяpydantic):

Что не может сделать определение типа?

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

Нет вывода типа времени выполнения

Интерпретатор времени выполнения (CPython) не пытается выводить информацию о типе во время выполнения или проверять параметры, переданные на основании этого.

Нет настройки производительности

Интерпретатор времени выполнения (CPython) не использует информацию о типе для оптимизации сгенерированного байт-кода для обеспечения безопасности или производительности.

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

Какой тип системы нужен?

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

Можно предположить, что он может иметь любой тип (т.е. он все еще является частью динамического типа).

И постепенно информируйте вашу кодовую базу о типах, например, об одной функции или переменной за раз:

Помните, только код с подсказками типа будет проверен на тип!

Когда вы запускаете linter (например, mypy) в коде с подсказками типов, в случае несоответствия типов возникает ошибка:

Этот код выдаст следующий вывод:

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

Как добавить информацию о типе

Как только вы решите добавить подсказку типа, вы обнаружите, что она может быть добавлена ​​в базу кода разными способами.

Type annotations

Типовые аннотации (Типовые аннотации) являются прямым способом и наиболее распространенным способом в типовых документах.

Читайте также:  базофилы что показывают в крови у взрослых

ИспользуетсяPEP-3107(Python 3.0+) Добавить аннотации функций и передатьPEP-526(Python 3.6+) Добавлены переменные аннотации. Это может сделать при написании кода,

Преимущества этого метода:

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

То есть в основном все типы информации обрабатываются как комментарии во время выполнения.

Чтобы разрешить эти противоречия, Python 3.7 представилPEP-563

Добавьте следующее утверждение, интерпретатор больше не будет создавать эти составные типы.

После того, как интерпретатор проанализирует синтаксическое дерево скрипта, он распознает подсказку типа и пропустит его оценку, оставив его в качестве исходной строки. Этот механизм заставляет подсказки типа происходить там, где они необходимы: проверка типа с помощью linter В Python 4 этот механизм станет поведением по умолчанию.

Type comments

Когда аннотации (аннотации типов) недоступны, вы можете использовать аннотации типов:

Пройдя по этому пути, мы получили некоторые преимущества:

Тип аннотации применяются к любой версии Python.

Хотя библиотека типов была добавлена ​​в стандартную библиотеку в Python 3.5+, она может использоваться как пакет PyPi для Python 2.7+. Кроме того, поскольку комментарии Python являются допустимой языковой функцией для любого кода Python, вы можете добавить подсказки типов в код на Python 2.7 или более поздней версии. Есть некоторые требования: комментарий подсказки типа должен быть в той же или следующей строке, где находится определение функции / переменной. Это также type: постоянные пуски.

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

Но это также создает некоторые новые проблемы:

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

Давайте кратко рассмотрим, как аннотации типов делают код более запутанным.

Вот фрагмент кода, который обменивает два значения атрибута в классе:

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

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

Но подождите, пока не добавите используемый тип:

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

Это теперь завершено. Затем шесть строк кода становятся шестнадцатью строками, и необходимо поддерживать больше кода!

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

Interface stub files

Таким образом, код поддерживается следующим образом:

В отличие от других методов, этот метод добавляет другой файл pyi рядом с исходным файлом:

Интерфейсные файлы не новы, C / C ++ использовался десятилетиями.

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

Конечно, есть некоторые относительно большие расходы:

Чтобы решить эти проблемы, первоначальный автор взял на себя задачу объединения заглушки с исходным файлом в mypy. Теоретически, эти две проблемы могут быть решены.python/mypy

issue 5208Проверьте прогресс в.

Docstrings

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

С положительной стороны:

Тем не менее, он имеет серьезные недостатки в следующих формах:

Какого типа информация должна быть добавлена

Давайте углубимся в конкретные детали. Полный список типов, которые можно добавить, см. ВОфициальные документы, Здесь я дам вам краткий 3-минутный обзор, чтобы понять это.

Существует два типа классификации: номинальные типы и типы утки (протоколы).

Nominal type

Источник

Python 3 Type Hints и статический анализ

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

Тип подсказки

Типовые подсказки строятся поверх аннотаций функций. Вкратце, аннотации функций позволяют вам аннотировать аргументы и возвращать значение функции или метода с произвольными метаданными. Подсказки типов представляют собой особый случай аннотаций функций, которые специально аннотируют аргументы функций и возвращаемое значение стандартными сведениями о типах. Аннотации функций в целом и подсказки типов в частности не являются обязательными. Давайте посмотрим на быстрый пример:

reverse_slice (‘abcdef’, 3, 5) ‘ed’ « `

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

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

reverse_slice (‘abcdef’, 3, 5) ‘ed’ « `

Как видите, код ведет себя одинаково, независимо от подсказок типа.

Мотивация для Типовых Подсказок

OK. Тип подсказки не являются обязательными. Типовые подсказки полностью игнорируются Python. Какой в ​​этом смысл? Ну, есть несколько веских причин:

Я углублюсь в статический анализ с Mypy позже. Поддержка IDE уже началась с поддержки PyCharm 5 для подсказок типов. Стандартная документация отлично подходит для разработчиков, которые могут легко определить тип аргументов и возвращаемое значение, просто взглянув на сигнатуру функции, а также на автоматические генераторы документации, которые могут извлечь информацию о типе из подсказок.

Модуль typing

Модуль ввода содержит типы, предназначенные для поддержки подсказок типов. Почему бы просто не использовать существующие типы Python, такие как int, str, list и dict? Вы можете определенно использовать эти типы, но из-за динамической типизации Python, помимо базовых типов, вы не получаете много информации. Например, если вы хотите указать, что аргумент может быть отображением между строкой и целым числом, нет способа сделать это со стандартными типами Python. С помощью модуля ввода это так же просто, как:

python Mapping[str, int]

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

« `python из набора импорта списка, Dict, Union

x = [dict (a = 1, b = 2), dict (c = 3, d = 4)] foo (x, ‘3’)

Полезные типы

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

Тип Callable позволяет вам указывать функцию, которая может быть передана в качестве аргумента или возвращена в результате, так как Python рассматривает функции как первоклассных граждан. Синтаксис для вызываемых элементов заключается в предоставлении массива типов аргументов (снова из модуля ввода), за которым следует возвращаемое значение. Если это сбивает с толку, вот пример:

Читайте также:  switchport port security mac address sticky что это

« `python def do_something_fancy (данные: Set [float], on_error: Callable [[Exception, int], None]):…

Функция обратного вызова on_error указывается как функция, которая принимает в качестве аргументов исключение и целое число и ничего не возвращает.

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

Тип Union, который вы видели ранее, полезен, когда аргумент может иметь несколько типов, что очень часто встречается в Python. В следующем примере функция verify_config () принимает аргумент config, который может быть либо объектом Config, либо именем файла. Если это имя файла, он вызывает другую функцию, чтобы проанализировать файл в объект Config и вернуть его.

« `python def verify_config (config: Union [str, Config]): если isinstance (config, str): config = parse_config_file (config)…

Тип Optional означает, что аргумент также может быть None. Optional[T] эквивалентен Union[T, None]

Есть еще много типов, которые обозначают различные возможности, такие как Iterable, Iterator, Reversible, SupportsInt, SupportsFloat, Sequence, MutableSequence и IO. Посмотрите документацию по модулю набора для полного списка.

Главное, что вы можете задавать тип аргументов очень детальным образом, который поддерживает систему типов Python с высокой точностью, а также допускает обобщенные и абстрактные базовые классы.

Переслать рекомендации

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

NameError: имя ‘A’ не определено « `

Что произошло? Класс A еще не определен, когда подсказка типа для его метода merge () проверяется Python, поэтому класс A нельзя использовать в этой точке (напрямую). Решение довольно простое, и я видел его раньше в SQLAlchemy. Вы просто указываете подсказку типа в виде строки. Python поймет, что это прямая ссылка, и поступит правильно:

Введите псевдонимы

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

« `Python Data = Dict [int, Sequence [Dict [str, Необязательный [List [float]]]]

Вспомогательная функция get_type_hints()

« `python print (A.merge. аннотации )

Атрибут annotations просто возвращает значение аннотации как есть. В данном случае это просто строка «A», а не объект класса A, на который «A» представляет собой прямую ссылку.

« `python print (get_type_hints (A.merge))

Функция get_type_hints () преобразовала тип другого аргумента в объединение A (класса) и NoneType из-за аргумента None по умолчанию. Тип возвращаемого значения также был преобразован в класс А.

Декораторы

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

Распространенным сценарием при использовании обычных аннотаций функций также является наличие декоратора, который работает над ними. В этом случае вы также хотите отключить проверку типов. Один из вариантов — использовать декоратор @no_type_check в дополнение к вашему декоратору, но он устареет. Вместо этого @no_Type_check_decorator можно использовать для украшения вашего декоратора, чтобы он также вел себя как @no_type_check (добавляет атрибут no_type_check ).

Позвольте мне проиллюстрировать все эти концепции. Если вы попытаетесь get_type_hint () (как это делает любая проверка типов) для функции, аннотированной обычной строковой аннотацией, get_type_hints () будет интерпретировать ее как прямую ссылку:

« `python def f (a: ‘некоторая аннотация’): pass

печати (get_type_hints (е))

SyntaxError: ForwardRef должен быть выражением — получил «некоторую аннотацию» « `

Чтобы избежать этого, добавьте декоратор @no_type_check, и get_type_hints просто возвращает пустой dict, а атрибут __annotations__ возвращает аннотации:

« `python @no_type_check def f (a: ‘некоторая аннотация’): pass

print (get_type_hints (f)) <>

python @no_type_check_decorator def print_annotations(f): @functools.wraps(f) def decorated(*args, **kwargs): print(f.__annotations__) return f(*args, **kwargs) return decorated

« `python @print_annotations def f (a: ‘некоторая аннотация’): pass

Вызов get_type_hints () также безопасен и возвращает пустой dict.

Статический анализ с Mypy

Mypy — это статическая программа проверки типов, которая послужила вдохновением для подсказок типов и модуля ввода. Сам Гвидо ван Россум является автором PEP-483 и соавтором PEP-484.

Установка Mypy

bash pip3 install git+git://github.com/JukkaL/mypy.git

Играя с Mypy

После установки Mypy вы можете просто запустить Mypy в своих программах. Следующая программа определяет функцию, которая ожидает список строк. Затем он вызывает функцию со списком целых чисел.

« `python от ввода списка импорта

def case_insensitive_dedupe (data: List [str]): «» »Преобразует все значения в нижний регистр и удаляет дубликаты» »» список возврата (set (x.lower () для x в данных))

print (case_insensitive_dedupe ([1, 2])) « `

При запуске программы она явно завершается с ошибкой во время выполнения:

plain python3 dedupe.py Traceback (most recent call last): File «dedupe.py», line 8, in print(case_insensitive_dedupe([1, 2, 3])) File «dedupe.py», line 5, in case_insensitive_dedupe return list(set(x.lower() for x in data)) File «dedupe.py», line 5, in return list(set(x.lower() for x in data)) AttributeError: ‘int’ object has no attribute ‘lower’

В чем проблема с этим? Проблема в том, что даже в этом очень простом случае неясно, какова основная причина. Это проблема типа входа? Или, возможно, сам код неверен и не должен пытаться вызвать метод lower () для объекта ‘int’. Другая проблема заключается в том, что если у вас нет 100% тестового покрытия (и, честно говоря, никто из нас не делает), то такие проблемы могут скрываться в каком-то непроверенном, редко используемом пути кода и обнаруживаться в худшее время в производстве.

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

plain (N) > mypy dedupe.py dedupe.py:8: error: List item 0 has incompatible type «int» dedupe.py:8: error: List item 1 has incompatible type «int» dedupe.py:8: error: List item 2 has incompatible type «int»

Это просто, указывает непосредственно на проблему и не требует выполнения большого количества тестов. Еще одно преимущество статической проверки типов заключается в том, что если вы фиксируете ее, вы можете пропустить динамическую проверку типов, за исключением случаев анализа внешних входных данных (чтения файлов, входящих сетевых запросов или ввода данных пользователем). Это также создает большую уверенность, насколько рефакторинг идет.

Вывод

Подсказки по типу и модуль ввода являются совершенно необязательными дополнениями к выразительности Python. Хотя они могут и не понравиться всем, для больших проектов и больших команд они могут быть незаменимы. Доказательством тому является то, что большие команды уже используют статическую проверку типов. Теперь, когда информация о типах стандартизирована, вам будет проще делиться кодом, утилитами и инструментами, которые ее используют. Среды IDE, такие как PyCharm, уже используют это для обеспечения лучшего опыта разработчика.

Источник

Информ портал о технике и не только