[英]How to add type annotations to custom dict subclass in python?
我有一个类似于defaultdict的自定义dict
子类,但将缺少的键传递给default_factory
以便它可以生成适当的值。
class KeyDefaultDict(dict):
__slots__ = ("default_factory",)
def __init__(self, default_factory, *args, **kwargs):
super().__init__(*args, **kwargs)
self.default_factory = default_factory
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
ret = self[key] = self.default_factory(key)
return ret
def __repr__(self):
return (
f"{type(self).__name__}({repr(self.default_factory)}, {super().__repr__()})"
)
d = KeyDefaultDict(int)
print(d["1"] + d["2"] + d["3"]) # out: 6
print(d) # out: KeyDefaultDict(<class 'int'>, {'1': 1, '2': 2, '3': 3})
我想像我的项目的其余部分一样为这个类添加类型注释,但我找不到任何如何做到这一点的示例。 我看到typing
模块使用外部类来添加注释。 例如, defaultdict
将使用typing.DefaultDict
进行注释,其定义为class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])
。
所以它是一个外部类,它typing.MutableMapping
defaultdict
和通用的typing.MutableMapping
。 但是,我认为他们可能这样做是因为他们不想更改原始collections.defaultdict
。 我找到了Generic
和Mapping
的子类示例,但没有找到从dict
其他东西继承的类。
问题是:如何为此类添加类型注释以使其成为通用类? 我是否需要扩展其他内容或为注释创建一个外部类?
我正在使用 python 3.7.5,我更喜欢直接从dict
继承,所以我不必实现所需的方法和性能原因。
提前致谢。
我很晚了,但我刚刚在我自己的代码库中完成了这项工作。
基本上,您需要使用类型映射泛型这是 dict 使用的泛型,因此您可以定义其他类型,如MyDict[str, int]
。
对于我的用例,我想要一个特殊的 dict,它可以清晰地格式化自己以进行日志记录,但我将在各种类型中使用它,因此它需要打字支持。
如何:
import typing
# these are generic type vars to tell mapping to accept any type vars when creating a type
_KT = typing.TypeVar("_KT") # key type
_VT = typing.TypeVar("_VT") # value type
# `typing.Mapping` requires you to implement certain functions like __getitem__
# I didn't want to do that, so I just subclassed dict.
# Note: The type you're subclassing needs to come BEFORE
# the `typing` subclass or the dict won't work.
# I had a test fail where my debugger showed that the dict had the items,
# but it wouldn't actually allow access to them
class MyDict(dict, typing.Mapping[_KT, _VT]):
"""My custom dict that logs a special way"""
def __str__(self):
# This function isn't necessary for your use-case, just including as example code
return clean_string_helper_func(
super(MyDict, self).__str__()
)
# Now define the key, value typings of your subclassed dict
RequestDict = MyDict[str, typing.Tuple[str, str]]
ModelDict = MyDict[str, typing.Any]
现在使用您的子类字典的自定义类型:
from my_project.custom_typing import RequestDict # Import your custom type
request = RequestDict()
request["test"] = ("sierra", "117")
print(request)
将输出为{ "test": ("sierra", "117") }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.