Python 2 __missing__ 方法

Python 2 __missing__ method

我写了一个非常简单的程序来子class 字典。我想尝试 python 中的 __missing__ 方法。 经过一些研究,我发现在 Python 2 中可以在 defaultdict 中使用。 (虽然在 python 3 中我们使用 collections.UserDict..) 如果找不到密钥,__getitem__ 负责调用 __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 的 class 定义有一个 __getitem__ 方法。但即便如此,假设我想自己写 __getitem__,我会怎么做?

dict 类型将总是 尝试调用 __missing__defaultdict 所做的只是提供一个实现;如果您提供自己的 __missing__ 方法,则根本不必继承 defaultdict

参见 dict documentation:

d[key]
Return the item of d with key key. Raises a KeyError if key is not in the map.

If a subclass of dict defines a method __missing__() and key is not present, the d[key] operation calls that method with the key key as argument. The d[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