5

我编写了一个非常简单的程序来子类化字典。我想试试__missing__python中的方法。经过一番研究,我发现在 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 的类定义有一个__getitem__方法。但即便如此,假设我想自己写__getitem__,我会怎么做?

4

1 回答 1

14

dict类型将始终尝试调用__missing__. 所做defaultdict的只是提供一个实现;如果您提供自己的__missing__方法,则根本不需要子类化defaultdict

请参阅dict文档

d[key]
使用键key 返回d的项目。引发一个if不在地图中。KeyError

如果 dict 的子类定义了一个方法__missing__()并且key不存在,则该操作使用 key key作为参数d[key]调用该方法。然后该操作返回或引发调用返回或引发的任何内容。没有其他操作或方法调用.d[key]__missing__(key)__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
于 2016-07-08T07:38:53.573 回答