对于将其他派生类的实例列表作为属性包含的类,正确的类型注释方式是什么? Bellow是一个具有两对基类和派生类的"简单"示例,我可以在其中重现我遇到困难解决的mypy个错误.

from dataclasses import dataclass
from typing import List, TypeVar

ClassType = TypeVar("ClassType", bound="BaseClass")


@dataclass
class BaseClass:
    a: int
    b: int


@dataclass
class DerivedClass(BaseClass):
    c: str


@dataclass
class BaseExample:
    list_attr: List[ClassType]  # line 20

    def validate(self, attrs: List[ClassType]) -> List[ClassType]:
        return [attr for attr in attrs if attr.a > 0]


@dataclass
class DerivedExample:
    list_attr: List[ClassType]  # Line 28  # Is actually List[DerivedClass]
    other_attr: int

    def select(self, attrs: List[ClassType]) -> List[ClassType]:
        return [attr for attr in attrs if attr.c] # line 32


ex = DerivedExample(list_attr=[DerivedClass(a=1, b=1, c="text")], other_attr=0)

我收到以下典型错误:

example.py:20: error: Type variable "example.ClassType" is unbound
example.py:20: note: (Hint: Use "Generic[ClassType]" or "Protocol[ClassType]" base class to bind "ClassType" inside a class)
example.py:20: note: (Hint: Use "ClassType" in function signature to bind "ClassType" inside a function)
example.py:28: error: Type variable "example.ClassType" is unbound
example.py:28: note: (Hint: Use "Generic[ClassType]" or "Protocol[ClassType]" base class to bind "ClassType" inside a class)
example.py:28: note: (Hint: Use "ClassType" in function signature to bind "ClassType" inside a function)
example.py:32: error: "ClassType" has no attribute "c"
Found 3 errors in 1 file (checked 1 source file)

类型==0.942

Python3.8.6

我在这里错误地使用了TypeVar吗? 我也试着按照答案here中的建议使用Generic,像BELLOW一样定义BaseClass,但它没有解决问题.

ClassType = TypeVar("ClassType", bound="BaseClass")

@dataclass
class BaseClass(Generic[ClassType]):
    a: int
    b: int

我也try 了不使用bound属性,如建议的in the documentation,但我得到了相同的错误.

有没有不同的方式来接近这个 struct ?

推荐答案

要消除20和28中的错误,可以使用泛型.然而,你必须使BaseExample成为通用的,而不是BaseClass.

@dataclass
class BaseExample(Generic[ClassType]):
    list_attr: List[ClassType]  # line 20

    def validate(self, attrs: List[ClassType]) -> List[ClassType]:
        return [attr for attr in attrs if attr.a > 0]

然而,要消除32中的错误,您必须定义一个绑定到DerivedClass的新类型var.为什么?因为属性cBaseClass中不可用,但在DerivedClass中引入.因此,将BaseClassDerivedExample放在一起使用是行不通的.

ClassType2 = TypeVar("ClassType2", bound="DerivedClass")
@dataclass
class DerivedExample(Generic[ClassType2]):
    list_attr: List[ClassType2]  # Line 28  # Is actually List[DerivedClass]
    other_attr: int

    def select(self, attrs: List[ClassType2]) -> List[ClassType2]:
        return [attr for attr in attrs if attr.c] # line 32

你可以试一试here种.

Python相关问答推荐

通过仅导入pandas来在for循环中进行多情节

剧作家Python没有得到回应

Pystata:从Python并行运行stata实例

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

pandas滚动和窗口中有效观察的最大数量

按顺序合并2个词典列表

如果值发生变化,则列上的极性累积和

如何让这个星型模式在Python中只使用一个for循环?

在ubuntu上安装dlib时出错

如何在Python中获取`Genericums`超级类型?

网格基于1.Y轴与2.x轴显示在matplotlib中

基于行条件计算(pandas)

导入错误:无法导入名称';操作';

循环浏览每个客户记录,以获取他们来自的第一个/最后一个渠道

如何在Python请求中组合多个适配器?

Python如何导入类的实例

用由数据帧的相应元素形成的列表的函数来替换列的行中的值

如何在Pandas中用迭代器求一个序列的平均值?

Django更新视图未更新

在聚合中使用python-polars时如何计算模式