#python #type-hinting
Вопрос:
Когда вы выполняете этот код:
from typing import Dict
bar: Dict[int, int, int] = dict()
возникает исключение TypeError
с сообщением Too many parameters for typing.Dict; actual 3, expected 2
. Но когда вы определяете переменную внутри функции:
from typing import Dict
def foo():
bar: Dict[int, int, int] = dict()
foo()
на этот раз не возникает никаких исключений. Это ожидаемое поведение или ошибка?
Ответ №1:
Это предполагаемое поведение и определено в PEP 526 — Синтаксис для аннотаций переменных #Эффекты выполнения аннотаций типов.
Аннотирование локальной переменной приведет к тому, что интерпретатор будет рассматривать ее как локальную, даже если она никогда не была назначена. Аннотации для локальных переменных оцениваться не будут:
def f(): x: NonexistentName # No error.
Однако, если он находится на уровне модуля или класса, то тип будет оценен:
x: NonexistentName # Error! class X: var: NonexistentName # Error!
Кроме того, PEP 563 — Отложенная оценка аннотаций определяет, что использование from __future__ import annotations
с python 3.7 предотвращает оценку этих аннотаций.
В этом ОПТОСОЗ предлагается изменить аннотации функций и аннотации переменных, чтобы они больше не оценивались во время определения функции. Вместо этого они сохраняются в __аннотациях__ в строковой форме.
from __future__ import annotations
from typing import Dict
bar: Dict[int, int, int] = dict() # no errors
Комментарии:
1. Что касается того, почему локальные аннотации не оцениваются, помните, что сама аннотация может быть произвольным кодом, а не просто подсказкой типа (хотя использование подсказок, не связанных с типом, не рекомендуется). Таким образом, было бы исключением оценивать аннотацию в определении функции, когда никакой другой код внутри функции не оценивается. PEP 563 делает это спорным вопросом, указывая, что аннотации не будут оцениваться ни при определении, ни во время вызова: аннотации становятся неявными
str
литералами, которые будут оцениваться только в том случае, если вы сделаете это явно.