对于包含其他派生类实例列表作为属性的类,键入注释的正确方法是什么。 波纹管是一个“简单”示例,具有两对基类和派生类,我可以在其中重现我无法解决的
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)
我收到以下 mypy 错误:
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)
mypy==0.942
Python 3.8.6
我在这里错误地使用了 TypeVar 吗? 我还尝试按照答案
here中的建议使用
Generic
,定义如下所示的BaseClass
,但它没有解决问题。
ClassType = TypeVar("ClassType", bound="BaseClass")
@dataclass
class BaseClass(Generic[ClassType]):
a: int
b: int
我也尝试不使用
bound
属性,如文档中所建议的那样,但我得到了相同的错误。
有没有不同的方法来处理这个结构?
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。为什么?因为属性
c
在
BaseClass
中不可用,而是通过
DerivedClass
引入的。因此,将
BaseClass
与
DerivedExample
一起使用是行不通的。
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
您可以在这里