如何使dict的子类尽可能“完美” ?最终目标是要有一个简单的字典,其中的键是小写的。
看来应该有一些微小的原语可以重写以完成此工作,但是根据我的所有研究和尝试,似乎并非如此:
如果我覆盖__getitem__/__setitem__,则get/ set不起作用。如何使它们工作?当然,我不需要单独实施它们吗?
__getitem__/__setitem__
我是否在阻止酸洗,我需要实施__setstate__等吗?
__setstate__
我是否需要repr,update以及__init__?
repr,update
__init__
我应该只使用mutablemapping(似乎不应该使用UserDict or DictMixin)吗?如果是这样,怎么办?这些文档并不完全具有启发性。
mutablemapping
UserDict or 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()
你可以使用collections模块中的ABC(抽象基类)轻松编写一个行为类似于dict的对象。它甚至会告诉你是否错过了一种方法,因此以下是关闭ABC的最低版本。
import collections class TransformedDict(collections.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 assert pickle.loads(pickle.dumps(s)) == s # works too since we just use a normal dict
我不会dict直接继承(或其他内置)。这通常没有任何意义,因为你实际要做的是实现dict的接口。而这正是ABC的目的。
dict直