【发布时间】:2021-06-06 20:15:59
【问题描述】:
我正在尝试这样做:
@dataclass
class A:
pass
@dataclass
class B(A):
pass
@dataclass
class container:
stuff: List[A OR B OR any future defined child class]
我通过查看这里和 PEP484 页面找到的唯一方法似乎是这样的......除了它不起作用
thing_co = TypeVar('thing_co', covariant=True)
class ListOfAOrLower(List[thing_co ]):
pass
@dataclass
class container:
stuff: ListOfAOrLower
当我尝试创建我的容器(即“container([B()])”)时,vscode 中的 pylance 说类型不兼容。当我尝试说“stuff”是一个 List[thing_co] 时,pylance 报告“TypeVar “thing_co”在这种情况下没有意义”。
我觉得我正在尝试做的事情非常简单,但我无法让类型检查器接受这个非常标准的表述。谁能建议如何根据我的意愿弯曲类型检查器?谢谢
【问题讨论】:
-
stuff: List[A]不够好有什么原因吗?据我记得,类型断言默认是协变的,所以类型检查器应该接受A的任何子类。您可能还想使用mypy来断言正确性,也许这是 pylance 中的一个错误。 -
这可能是一个错误,这是一个好点。我看看有没有什么报道。我使用 pylance 是因为根据我的经验,它比其他所有东西都要好 1000 倍。 List[A] 绝对没有用,这就是我认为没问题的,它大惊小怪。编辑:它可能是与数据类装饰器如何工作的交互。也许我会手动创建那个类。
-
一个列表是不变的,因为它既可以被写入也可以被读取。 List 包含“A 或子类”是没有意义的,如果你强迫它这样做可能会引入微妙的错误。您是否打算将
container泛型化为A的某些特定 子类? -
看来确实是数据类问题。只是把它变成了一个带有用户定义的 init 函数的数据类,并且接受了类型提示。
-
@MisterMiyagi 我不完全理解。为了使这更简单,我正在加载一个非常简单的 excel 文件,因此我不必费心为这个应用程序制作真正的 UI,而且我基本上有 2 种文件格式略有不同。版本 A 有 X、Y、Z 列。版本 B 有 W、X、Y、Z。所以我想要一个通用函数来加载它,但实际的消费者知道它是否期望 A 或 B 数据。我只是想让装载机不知道。基本上我不想复制粘贴相同的 10 行 openpyxl 代码:)
标签: python python-typing python-dataclasses