Общие типы
typing.TypeVar
является универсальным типом завода. Его основная цель - служить параметром / заполнителем для аннотаций обобщенной функции / класса / метода:
`` `импорт печатать
T = typing.TypeVar ("T")
def get_first_element (l: typing.Sequence [T]) -> T: "" "Получает первый элемент последовательности." "" return l [0]
Добавление типов в функцию
Давайте рассмотрим пример функции, которая получает два аргумента и возвращает значение, указывающее их сумму:
def two_sum(a, b):
return a + b
Глядя на этот код, один не может безопасно и без сомнения указать тип аргументов для функции two_sum
.Он работает как при поставке с int
значения:
print(two_sum(2, 1)) # result: 3
и со строками:
print(two_sum("a", "b")) # result: "ab"
а также с другими значениями, например, list
с, tuple
ов и так далее.
Из-за этой динамической природы типов Python, где многие из них применимы для данной операции, любая программа проверки типов не сможет обоснованно утверждать, следует ли разрешить вызов этой функции или нет.
Чтобы помочь нашей проверке типов, мы можем теперь предоставить подсказки для нее в определении функции, указывающие тип, который мы разрешаем.
Для того, чтобы указать , что мы хотим , чтобы int
типы мы можем изменить наше определение функции выглядеть следующим образом :
def two_sum(a: int, b: int):
return a + b
Аннотации следовать имя аргумента и отделены друг от друга :
характер.
Точно так же, чтобы указать только str
тип разрешен, мы бы изменить нашу функцию , чтобы определить его:
def two_sum(a: str, b: str):
return a + b
Помимо указания типа аргументов, можно также указать возвращаемое значение вызова функции. Это делается путем добавления ->
символа с последующим типом после закрывающей скобки в списке аргументов , но до того , как :
в конце объявления функции:
def two_sum(a: int, b: int) -> int:
return a + b
Теперь мы показали , что возвращаемое значение при вызове two_sum
должно быть типа int
.Точно так же мы можем определить соответствующие значения для str
, float
, list
, set
и другие.
Хотя подсказки типов в основном используются средствами проверки типов и средами разработки, иногда вам может потребоваться получить их. Это может быть сделано с помощью __annotations__
специального атрибута:
two_sum.__annotations__
# {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
Члены класса и методы
class A:
x = None # type: float
def __init__(self, x: float) -> None:
"""
self should not be annotated
init should be annotated to return None
"""
self.x = x
@classmethod
def from_int(cls, x: int) -> 'A':
"""
cls should not be annotated
Use forward reference to refer to current class with string literal 'A'
"""
return cls(float(x))
Прямая ссылка на текущий класс необходима, так как аннотации оцениваются, когда функция определена. Прямые ссылки также можно использовать при обращении к классу, который при импорте вызывает циклический импорт.
Переменные и атрибуты
Переменные комментируются с помощью комментариев:
x = 3 # type: int
x = negate(x)
x = 'a type-checker might catch this error'
Начиная с Python 3.6, есть также новый синтаксис для переменных аннотаций.Код выше может использовать форму
x: int = 3
В отличие от комментариев, также можно просто добавить подсказку типа в переменную, которая не была ранее объявлена, без установки значения:
y: int
Кроме того , если они используются в модуле или на уровне класса, намеки типа могут быть получены с помощью typing.get_type_hints(class_or_module)
:
class Foo:
x: int
y: str = 'abc'
print(typing.get_type_hints(Foo))
# ChainMap({'x': <class 'int'>, 'y': <class 'str'>}, {})
Кроме того , они могут быть доступны с помощью __annotations__
специальной переменной или атрибута:
x: int
print(__annotations__)
# {'x': <class 'int'>}
class C:
s: str
print(C.__annotations__)
# {'s': <class 'str'>}
NamedTuple
Создание namedtuple с намеками типа осуществляется с помощью функции NamedTuple из typing
модуля:
import typing
Point = typing.NamedTuple('Point', [('x', int),('y', int)])
Обратите внимание, что имя результирующего типа является первым аргументом функции, но его следует назначить переменной с тем же именем, чтобы упростить работу контролеров типов.
Введите подсказки для аргументов ключевых слов
def hello_world(greeting: str = 'Hello'):
print(greeting + ' world!')
Обратите внимание на пробелы вокруг знака равенства, в отличие от того, как обычно вводятся ключевые аргументы.