gpt4 book ai didi

python - Mypy 不识别具有继承的类类型

转载 作者:行者123 更新时间:2023-12-05 03:48:22 25 4
gpt4 key购买 nike

我无法让 Mypy 在这里识别正确的类型。我想要做的就是为类创建一个 dict 名称,这样我就可以通过提供作为其属性的 type_name 来获取该类。也许是因为 dataclassdataclasses-json 东西混淆了?

# mypy_test.py

from dataclasses import dataclass
from typing import Any, Dict, Type, TypeVar

from dataclasses_json import DataClassJsonMixin


@dataclass
class _BaseDataItem(DataClassJsonMixin):
name: str # functions as an ID. Subclasses should NOT modify its value after creation.
type_name: str
body: Any = None
# etc ...


@dataclass
class DatanetItem(_BaseDataItem):
type_name: str = "datanet"


@dataclass
class RedshiftItem(_BaseDataItem):
type_name: str = "redshift"


# https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-type-of-class-objects
IT = TypeVar("IT", bound=_BaseDataItem)

items2classes: Dict[str, Type[IT]] = {
c.type_name: c for c in (DatanetItem, RedshiftItem)
}


def create_obj(name: str, item_type: str) -> _BaseDataItem:
klass = items2classes[item_type]
obj = klass(name)
return obj

示例用法:

In [1]: import mypy_test as m

In [2]: m.create_obj('123','datanet')
Out[2]: DatanetItem(name='123', type_name='datanet', body=None)

In [3]: m.create_obj('mytable','redshift')
Out[3]: RedshiftItem(name='mytable', type_name='redshift', body=None)

即使我认为我遵循了说明 in the docs ,出于某种原因,MyPy 一直给我这个错误:

mypy_test.py:28: error: Type variable "mypy_test.IT" is unbound
mypy_test.py:28: note: (Hint: Use "Generic[IT]" or "Protocol[IT]" base class to bind "IT" inside a class)
mypy_test.py:28: note: (Hint: Use "IT" in function signature to bind "IT" inside a function)
mypy_test.py:35: error: Cannot instantiate type "Type[IT?]"
Found 2 errors in 1 file (checked 1 source file)

最佳答案

mypy 失败的原因与 dataclasses 或 dataclasses-json 无关。如果您尝试简化您的示例,使所有内容都是常规对象,您仍然会遇到相同的错误。

这是因为不幸的是,您正试图将 TypeVars 用于它们从未打算做的事情。

TypeVars 旨在用于类定义或函数定义中:它们让您“捕获”用户提供的类型的值,并在类定义/函数定义的其他部分中重复使用。每次用户实际尝试使用您的类或函数时,都会执行此“捕获”或“匹配”。

但由于 items2class 不是泛型类或函数的一部分,mypy 最终会合理地提示您正试图在您打算使用它的上下文之外使用 TypeVar。

值得庆幸的是,在这种情况下,解决方案相对简单:停止使用泛型,改为让您的字典成为 Dict[Str, Type[_BaseDataItem]] 类型。您的子类一开始都是 _BaseDataItem 类型,因此它们是可以插入到此字典中的有效项目。

如果您想要更精确的类型提示——例如让 mypy 理解在使用字典时键“redshift”正好对应于 RedshiftItem——您也许可以尝试使用 TypedDicts 进行试验.但我不确定这对您的代码上下文是否真的有帮助。

关于python - Mypy 不识别具有继承的类类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64449852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com