如何使 dict 的子类尽可能“完美” ?最终目标是有一个简单的 字典 ,其中的键是小写的。
似乎应该有一些我可以重写的小原语来完成这项工作,但根据我所有的研究和尝试,情况似乎并非如此:
如果我覆盖__getitem__/__setitem__,那么get/set不起作用。我怎样才能让它们工作?当然我不需要单独实施它们吗?
__getitem__
__setitem__
get
set
我是否阻止酸洗工作,我是否需要实施__setstate__等?
__setstate__
我需要repr和update吗__init__?
repr
update
__init__
我应该只使用可变映射(似乎不应该使用UserDict or DictMixin)吗?如果是这样,怎么做?这些文档并不完全有启发性。
UserDict
DictMixin
这是我的第一次尝试,它get()不起作用,毫无疑问还有许多其他小问题:
get()
class arbitrary_dict(dict): """A dictionary that applies an arbitrary key-altering function before accessing the keys.""" def __keytransform__(self, key): return key # Overridden methods. List from # https://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict def __init__(self, *args, **kwargs): self.update(*args, **kwargs) # Note: I'm using dict directly, since super(dict, self) doesn't work. # I'm not sure why, perhaps dict is not a new-style class. def __getitem__(self, key): return dict.__getitem__(self, self.__keytransform__(key)) def __setitem__(self, key, value): return dict.__setitem__(self, self.__keytransform__(key), value) def __delitem__(self, key): return dict.__delitem__(self, self.__keytransform__(key)) def __contains__(self, key): return dict.__contains__(self, self.__keytransform__(key)) class lcdict(arbitrary_dict): def __keytransform__(self, key): return str(key).lower()
您可以使用模块中的ABC s(抽象基类)dict轻松编写行为类似于 a 的对象。它甚至会告诉您是否错过了某个方法,因此下面是关闭 ABC 的最小版本。collections.abc
dict
collections.abc
from collections.abc import MutableMapping class TransformedDict(MutableMapping): """A dictionary that applies an arbitrary key-altering function before accessing the keys""" def __init__(self, *args, **kwargs): self.store = dict() self.update(dict(*args, **kwargs)) # use the free update to set keys def __getitem__(self, key): return self.store[self._keytransform(key)] def __setitem__(self, key, value): self.store[self._keytransform(key)] = value def __delitem__(self, key): del self.store[self._keytransform(key)] def __iter__(self): return iter(self.store) def __len__(self): return len(self.store) def _keytransform(self, key): return key
您可以从 ABC 获得一些免费方法:
class MyTransformedDict(TransformedDict): def _keytransform(self, key): return key.lower() s = MyTransformedDict([('Test', 'test')]) assert s.get('TEST') is s['test'] # free get assert 'TeSt' in s # free __contains__ # free setdefault, __eq__, and so on import pickle # works too since we just use a normal dict assert pickle.loads(pickle.dumps(s)) == s
我不会dict直接继承(或其他内置函数)。这通常是没有意义的,因为你真正想做的是 实现 a 的接口dict。这正是 ABC 的用途。