Что такое аннотации переменных?
Аннотации переменных - это всего лишь следующий шаг от комментариев # type
, как они были определены в PEP 484
; обоснование этого изменения выделено в соответствующем разделе PEP 526 .
Итак, вместо того, чтобы указывать тип с помощью:
primes = [] # type: List[int]
Был введен новый синтаксис, позволяющий напрямую аннотировать тип с помощью присвоения формы:
primes: List[int] = []
который, как указал @Martijn, обозначает список целых чисел с использованием типов, доступных в _5 _ и инициализируя его пустым списком.
Какие изменения это принесет?
Первым внесенным изменением был новый синтаксис, который позволяет аннотировать имя типом, либо отдельно после символа :
, либо, необязательно, аннотировать, одновременно присваивая ему значение:
annotated_assignment_stmt ::= augtarget ":" expression ["=" expression]
Итак, рассматриваемый пример:
primes: List[int] = [ ]
# ^ ^ ^
# augtarget | |
# expression |
# expression (optionally initialize to empty list)
Вместе с новым синтаксисом были также внесены дополнительные изменения; модули и классы теперь имеют атрибут __annotations__
(как и функции с PEP 3107 - - Аннотации функций), к которым прикреплены метаданные типа:
from typing import get_type_hints # grabs __annotations__
Теперь __main__.__annotations__
содержит объявленные типы:
>>> from typing import List, get_type_hints
>>> primes: List[int] = []
>>> captain: str
>>> import __main__
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int]}
captain
в настоящее время не отображается через get_type_hints
, поскольку возвращает только get_type_hints
типы, к которым также можно получить доступ в модуле; т.е. ему сначала нужно значение:
>>> captain = "Picard"
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int], 'captain': <class 'str'>}
Использование print(__annotations__)
покажет 'captain': <class 'str'>
, но вам действительно не следует обращаться к __annotations__
напрямую.
Аналогично для классов:
>>> get_type_hints(Starship)
ChainMap({'stats': typing.Dict<~KT, ~VT>[str, int]}, {})
Где ChainMap
используется для захвата аннотаций для данного класса (расположенного в первом сопоставлении) и всех аннотаций, определенных в базовых классах, найденных в его mro
(последующие сопоставления, {}
для объекта).
Наряду с новым синтаксисом был добавлен новый тип ClassVar
для обозначения переменных класса. Ага, stats
в вашем примере на самом деле является переменной экземпляра, а не ClassVar
.
Меня заставят его использовать?
Как и подсказки типа из PEP 484
, они полностью необязательны и в основном используются для инструментов проверки типов (и всего, что вы можете создать на основе этой информации). Он будет временным, когда выйдет стабильная версия Python 3.6, поэтому в будущем могут быть добавлены небольшие изменения.
person
Dimitris Fasarakis Hilliard
schedule
11.10.2016
primes: List[int] = []
- это просто пустой список какprimes = []
. Разница в том, что вы утверждаете, чтоprimes
должен содержать толькоint
s, и сторонние приложения могут ввести проверку вашей программы, чтобы проверить это утверждение, но когда вы запустите код в любой интерпретатор Python, аналогичный записиprimes = []
, и, таким образом, выполнениеprimes: List[int] = []; primes.append("string")
по-прежнему действителен. - person Bakuriu   schedule 11.10.2016