Python 2 __missing__方法

时间:2016-07-08 07:27:13

标签: python dictionary python-2.x dictionary-missing

我写了一个非常简单的程序来子类化字典。我想在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的类定义有一个__getitem__方法。但即便如此,说我想写自己的__getitem__,我该怎么做?

1 个答案:

答案 0 :(得分:8)

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

请参阅dict documentation

  

<强> d[key]
  使用键返回 d 项。如果不在地图中,则引发KeyError

     

如果dict的子类定义方法__missing__()并且 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