Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Protocol和TypeVar指定任意数据类的Python类型提示_Python_Type Hinting_Typing_Mypy - Fatal编程技术网

使用Protocol和TypeVar指定任意数据类的Python类型提示

使用Protocol和TypeVar指定任意数据类的Python类型提示,python,type-hinting,typing,mypy,Python,Type Hinting,Typing,Mypy,我正在编写一个可以在内存中存储任意数据类的类。在这里,我试图指定要存储的实例必须是一个数据类,并且必须有一个id字段。还可以通过指定类和实例的id来获取实例 我正在努力定义正确的类型提示。我已经弄明白了,我(可能)需要一个TypeVar和Protocol的组合。这是我当前的代码: 导入键入 导入uuid 从集合导入defaultdict 从数据类导入字段,数据类 类DataclassWithId(typing.Protocol): __数据类\字段\键入.Dict id:str Klass=ty

我正在编写一个可以在内存中存储任意数据类的类。在这里,我试图指定要存储的实例必须是一个数据类,并且必须有一个
id
字段。还可以通过指定类和实例的id来获取实例

我正在努力定义正确的类型提示。我已经弄明白了,我(可能)需要一个
TypeVar
Protocol
的组合。这是我当前的代码:

导入键入
导入uuid
从集合导入defaultdict
从数据类导入字段,数据类
类DataclassWithId(typing.Protocol):
__数据类\字段\键入.Dict
id:str
Klass=typing.TypeVar(“Klass”,bound=DataclassWithId)
在MemoryDataClassStore中初始化:
定义初始化(自):
self.\u data\u store=defaultdict(lambda:dict())
def add(自我,实例:Klass):
store\u for\u class=self.\u get\u store\u for\u class(实例.\uuuuu class\uuuu)
为\u类[instance.id]=实例存储\u
def get(self,klass:typing.Type[klass],id\ux:str)->klass:
返回self.\u获取\u存储\u用于\u类(klass)[id\uu]
def get_all(self,klass)->键入.List[klass]:
返回列表(self.\u获取\u存储\u用于\u类(klass).values())
def_获取_存储_用于_类(
self,klass:typing.Type[klass]
)->键入.Dict[str,Klass]:
返回自我数据存储[klass]
auto\u uuid\u field=field(默认值\u factory=lambda:str(uuid.uuid4())
@数据类
A类:
姓名:str
id:str=自动\u uuid\u字段
store=InMemoryDataClassStore()
实例a=ClassA(name=“foo”)
store.add(实例a)
打印(store.get(klass=ClassA,id=instance\u a.id).name)
打印(store.get(klass=ClassA,id=instance\u a.id).other\u name)#应该会导致键入错误
如果对该文件运行
mypy
,则

in_memory_data_store.py:45: error: Value of type variable "Klass" of "add" of "InMemoryDataClassStore" cannot be "ClassA"
in_memory_data_store.py:46: error: Value of type variable "Klass" of "get" of "InMemoryDataClassStore" cannot be "ClassA"
in_memory_data_store.py:47: error: Value of type variable "Klass" of "get" of "InMemoryDataClassStore" cannot be "ClassA"
in_memory_data_store.py:47: error: "ClassA" has no attribute "other_name"  # expected
有人能帮我了解一下字体提示吗

最好的
Lars

MisterMiyagi将我指向Github上的mypy问题跟踪器,其中指出,
协议
无法匹配数据类:

带有ID的类(键入.Protocol):
id:str
Klass=typing.TypeVar(“Klass”,bound=WithId)

只需从
typing.Protocol
子类中删除
\uuuuu dataclass\u fields\uuuuuuuu
,一切都能正常工作。实际上,对于我的代码来说,它是否是数据类并不重要。它只需要一个
id
字段,该字段与
键入一起工作。协议

这是否回答了您的问题?正如链接的问答所指出的,。感谢Mistermiagi在mypy tracker上为我指出这个问题。对于我试图做的,存储的类是否是
dataclasses
,其实并不重要。因此,只要删除
\uuuuu数据类\u字段\uuuuuu
一切正常,我认为这是一个构造特别好的问题,感谢您的发布。