Рекурсивная типизация в Python 3.5+

В Python 3.5 были добавлены аннотации типов (см. здесь).

Есть ли способ определить аннотации рекурсивного типа, например, для древовидной структуры?

class Employee(object):
    def __init__(self, name: str, reports: List[Employee]):
       self.name = name
       self.reports = reports

В приведенном выше не похоже, что аннотация List[Employee] работает. Запуск кода приводит к этой ошибке:

NameError: name 'Employee' is not defined


person nimda    schedule 13.07.2016    source источник


Ответы (1)


Вы можете использовать прямые ссылки, как определено в PEP 484.

Обычно это происходит при определении класса-контейнера, где определяемый класс встречается в сигнатуре некоторых методов. Например, следующий код (начало реализации простого бинарного дерева) не работает:

class Tree:
    def __init__(self, left: Tree, right: Tree):
        self.left = left
        self.right = right

Чтобы решить эту проблему, мы пишем:

class Tree:
    def __init__(self, left: 'Tree', right: 'Tree'):
        self.left = left
        self.right = right

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

class Tree:
    ...
    def leaves(self) -> List['Tree']:
person Brendan Abel    schedule 13.07.2016
comment
Обратите внимание, что в этом нет необходимости, начиная с Python3.10, и этого можно избежать с помощью from __future__ import annotations, см. таблицу внизу docs.python.org/3.8/library/__future__.html - person M. Volf; 31.12.2020