带有子类和类列表的Python类型注释

带有子类和类列表的Python类型注释,python,python-3.x,typehints,Python,Python 3.x,Typehints,对于自然包含自身其他实例列表的类,在Python类型注释中注意这一点的正确方法是什么,这样子类就可以工作了 为了给出具体的讨论内容,下面是一个使用基本树类型和子类的示例 from typing import List, Optional, TypeVar T = TypeVar('T', bound='TreeBase') class TreeBase(object): def __init__(self : T) -> None: self.parent =

对于自然包含自身其他实例列表的类,在Python类型注释中注意这一点的正确方法是什么,这样子类就可以工作了

为了给出具体的讨论内容,下面是一个使用基本树类型和子类的示例

from typing import List, Optional, TypeVar

T = TypeVar('T', bound='TreeBase')

class TreeBase(object):
    def __init__(self : T) -> None:
        self.parent = None # type: Optional[T]
        self.children = [] # type: List[T]

    def addChild(self : T, node : T) -> None:
        self.children.append(node)
        node.parent = self

class IdTree(TreeBase):
    def __init__(self, name : str) -> None:
        super().__init__()
        self.id = name      

    def childById(self : 'IdTree', name : str) -> Optional['IdTree']:
        for child in self.children:
            if child.id == name: # error: "T" has no attribute "id"
                return child # error: Incompatible return value type (got "T", expected "Optional[IdTree]")
        return None
我在mypy版本0.600(pip3默认值)和0.650(github的最新版本)中遇到错误


指定此项的正确方法是什么?

尝试使用var类型使整个类成为泛型

我认为您也不需要在
TreeBase
中注释
self
,因为您不是从这些方法返回它,也不是以一般方式使用它

from typing import Generic, List, Optional, TypeVar

T = TypeVar("T", bound="TreeBase")


class TreeBase(Generic[T]):
    def __init__(self) -> None:
        self.parent: Optional[T] = None
        self.children: List[T] = []

    def addChild(self, node: T) -> None:
        self.children.append(node)
        node.parent = self


class IdTree(TreeBase["IdTree"]):  # No TypeVar, subclass is non-generic.
    def __init__(self, name: str) -> None:
        super().__init__()
        self.id = name

    def childById(self, name: str) -> Optional["IdTree"]:
        for child in self.children:
            if child.id == name:
                return child
        return None