将__getitem__与下标一起使用super

时间:2019-05-05 14:06:49

标签: python super

我正在写一个dict,它只包含正整数的元组作为键。如果键未知,并且元组的元素之一为1,则查找应返回默认值0。任何其他未知密钥都应引发KeyError

这很好:

class zeroDict(dict):
    '''
    If key not in dict and an element of the tuple is 
    a 1, impute the value 0.
    '''    
    def __init__self():
        super().__init__()
    def __getitem__(self, key):
        try:
            return super().__getitem__(key)
        except KeyError:
            if 1 in key:
                return 0
            else:
                raise   

这不是:

class zDict(dict):
    '''
    If key not in dict and an element of the tuple is 
    a 1, impute the value 0.
    '''    
    def __init__self():
        super().__init__()
    def __getitem__(self, key):
        try:
            return super()[key]
        except KeyError:
            if 1 in key:
                return 0
            else:
                raise  

当我尝试从zDict读取值时,我得到TypeError: 'super' object is not subscriptable

实现之间的唯一区别是zeroDict表示

return super().__getitem__(key) 

zDict

return super()[key]

但是,help(dict.__getitem__)可以打印

__getitem__(...)
    x.__getitem__(y) <==> x[y]   

这似乎表明这两个语句是等效的。这里发生了什么?

1 个答案:

答案 0 :(得分:0)

正如其他人所解释的那样,super()在此处不起作用的原因是因为它返回了超级对象,该对象是处理对下一个类分配点属性访问的代理对象按照方法解析顺序。

话虽这么说,您不应该在这里覆盖__getitem__,python数据模型为这种情况提供了 ,它是__missing__ method

  

object.__missing__(self, key)

     当key不位于字典中时,字典子类的

实现self[key]   字典。由dict.__getitem__()

调用

因此,请执行以下操作:

class ZeroDict(dict):
    def __missing__(self, key):
        if 0 in key:
            return 0
        else:
            raise KeyError(key)

还有一个演示:

>>> class ZeroDict(dict):
...     def __missing__(self, key):
...         if 0 in key:
...             return 0
...         else:
...             raise KeyError(key)
...
>>> d = ZeroDict()
>>> d[(1, 0)] = 'foo'
>>> d
{(1, 0): 'foo'}
>>> d[1, 0]
'foo'
>>> d[1, 1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __missing__
KeyError: (1, 1)
>>> d[0, 1]
0
>>>