我写了一个非常简单的程序来对字典进行子类化。我想在 python 中尝试 __missing__ 方法。 经过一些研究,我发现在 Python 2 中,它在 defaultdict 中可用。 (虽然在 python 3 中我们使用 collections.UserDict..) __getitem__ 负责在未找到 key 时调用 __missing__ 方法。
当我在下面的程序中实现 __getitem__ 时,我得到了一个关键错误,但是当我在没有它的情况下实现时,我得到了想要的值。
import collections
class DictSubclass(collections.defaultdict):
def __init__(self,dic):
if dic is None:
self.data = None
else:
self.data = dic
def __setitem__(self,key,value):
self.data[key] = value
########################
def __getitem__(self,key):
return self.data[key]
########################
def __missing__(self,key):
self.data[key] = None
dic = {'a':4,'b':10}
d1 = DictSubclass(dic)
d2 = DictSubclass(None)
print d1[2]
我想我需要实现 __getitem__ 因为它负责调用 __missing__。我知道 defaultdict 的类定义有一个 __getitem__ 方法。但即便如此,假设我想编写自己的 __getitem__,我该怎么做?
请您参考如下方法:
dict 类型将总是尝试调用__missing__。 defaultdict 所做的只是提供一个实现;如果您提供自己的 __missing__ 方法,则根本不需要子类化 defaultdict。
参见 dict documentation :
d[key]
Return the item of d with key key. Raises aKeyErrorif key is not in the map.If a subclass of dict defines a method
__missing__()and key is not present, thed[key]operation calls that method with the key key as argument. Thed[key]operation then returns or raises whatever is returned or raised by the__missing__(key)call. No other operations or methods invoke__missing__().
但是,您需要保留默认的 __getitem__ 方法,或者至少调用它。如果您使用自己的版本覆盖 dict.__getitem__ 并且不调用基本实现,则永远不会调用 __missing__。
您可以从您自己的实现中调用 __missing__:
def __getitem__(self, key):
if key not in self.data:
return self.__missing__(key)
return self.data[key]
或者您可以调用原始实现:
def __getitem__(self, key):
if key not in self.data:
return super(DictSubclass , self).__getitem__(key)
return self.data[key]
在 Python 2 中,你可以继承 UserDict.UserDict :
from UserDict import UserDict
class DictSubclass(UserDict):
def __missing__(self, key):
self.data[key] = None
