Subclass dict __getitem__ 同时保持原始 class 类型

Subclass dict __getitem__ while maintaining original class type

我正在尝试子class python 字典 __getitem__ 方法,同时在访问散列时保持原始 class 类型。 properly subclassing or perfect overriding 中没有答案似乎可以解决这个问题。例如,

class MyDict(dict):
    def __init__(self, data=None):
        if not data:
            data = {}
        dict.__init__(self, data)

    def __getitem__(self, key):
        if key == 'b':
            print('Found "b"')

        return dict.__getitem__(self, key)

shallow_dict = MyDict(data={
    'b': 'value'
})

# prints Found "b", as expected
x = shallow_dict['b']

deep_dict = MyDict(data={
    'a': {
        'b': 'value'
    }
})

# prints nothing
x = deep_dict['a']['b']

发生这种情况是因为当我们访问 ['b'] 时,我们实际上访问的是 dict,而不是 MyDict。所以我试图通过将内容复制到一个新对象中来解决这个问题:

def __getitem__(self, key):
    data = dict.__getitem__(self, key)
    if key == 'b':
        print('Found "b"')

    if isinstance(data, dict):
        return MyDict(data)
    return data

但是,此解决方案在将内容写入哈希时会导致新问题,因为我返回的是副本而不是参考:

deep_dict['a']['b'] = 'other value'

# prints 'value'
print(deep_dict['a']['b'])

关于如何正确维护类型的任何建议,因为复制有这种副作用?

你的 MyDict 只是作为字典的 proxy 怎么样:

class MyDict(object):
    def __init__(self, data={}):
        self.data = data

    def __getitem__(self, key):
        if key == 'b':
            print('Found "b"')
        return MyDict(self.data.__getitem__(key))

    def __setitem__(self, key, value):
        return self.data.__setitem__(key, value)

    def __repr__(self):
        return self.data.__repr__()

    # add more __magic__ methods as you wish

shallow_dict = MyDict({
    'b': 'value'
})

x = shallow_dict['b']


deep_dict = MyDict({
    'a': {
        'b': 'value'
    }
})

x = deep_dict['a']['b']

# assignment
deep_dict['a']['a'] = {'b': 'here'}
deep_dict['a']['a']['b']
print(deep_dict)

输出:

Found "b"
Found "b"
Found "b"
{'a': {'b': 'value', 'a': {'b': 'here'}}}

如您所见,当您在 __getitem__ 中获取 self.data 时,它只是通过引用新的 MyDict 对象来传递 self.data.__getitem__ 的结果。