Skip to main content
 首页 » 编程设计

Python 2 __missing__ 方法

2025年05月04日10sky-heaven

我写了一个非常简单的程序来对字典进行子类化。我想在 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 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