如果模拟一个dict,在python中为__getitem __()子类化对象的正确方法

时间:2015-01-30 18:51:44

标签: python python-2.7

什么是子类object.__getitem__()的正确方法,但是回归到默认行为?我想让它看起来像一个动态(但始终如一)为任何可能的键行为的字典。

class MyObj(object):
    """MyObj()[k] returns 1 for any key k that ends in '_q',
       default item lookup behavior otherwise"""
    mypattern = re.compile(r'_q$')
    def __getitem__(self, k):
        if self.mypattern.match(k):
            return 1
        else:
            ???

我尝试拨打return super(TFConverter, self).__getitem__(k)并告诉我AttributeError: 'super' object has no attribute '__getitem__'

2 个答案:

答案 0 :(得分:4)

如果您希望模拟类似dict的界面,则应该在项目不存在时提出KeyError,就像dict那样。当您的密钥是字符串时,往往就是这种情况。

def __getitem__(self, k):
    if self.mypattern.match(k):
        return 1
    else:
        raise KeyError("Key {} does not match pattern {}".format(k, self.mypattern))

如果您希望对象像list一样工作(通常情况下,如果它有整数键),则应该引发IndexError

调用super().__getitem__不起作用,因为object未定义__getitem____getitem__仅存在于支持下标的对象上。因此,如果要委托超类的__getitem__实现,则必须确保对子类进行子类化(例如dict)。

另一种用例是在找不到密钥时返回默认值。例如,这是collections.defaultdict的纯Python释义(真实版本用C语言编写):

class defaultdict(dict):
    # default_factory is a function which supplies the default value when a key is not found
    def __init__(self, default_factory):
        self.default_factory = default_factory

    def __getitem__(self, key):
        if key in self:
            # the super() call works here because we are
            # subclassing dict, which supports __getitem__
            return super().__getitem__(key)
        if self.default_factory is not None:
            val = self.default_factory(key)
            self[key] = val
            return val
        raise KeyError(key)

答案 1 :(得分:0)

没有object.__getitem__。为了能够调用__getitem__的基类实现,您需要从实际拥有一个的类继承。鉴于此,您的super调用将正常工作。