如何改变python字典的__setattr__的行为?

ame*_*hta 4 python customization dictionary types internals

在Python中,一切都有一个类.因此dict也有一类.

所以,从理论上讲,我应该能够改变keyvalue赋值行为的实现.


例:

d = dict()
d['first'] = 3    # Internally d['first'] is stored as 6 [i.e. value*2 if value is INT]

print d['first']  # should print 6

d['second'] = 4 

print d['second'] # should print 8
Run Code Online (Sandbox Code Playgroud)


我注意到大多数对象都有OBJECT.__dict__或列出的属性vars(OBJECT).但是,这是不是情况dictlist.

如何通过覆盖dict.__setattr__()方法获得所需的行为?

jsb*_*eno 11

__setitem__是在这种情况下被覆盖-这是为simples:

class MyDict(dict):
    def __setitem__(self, key, value):
         dict.__setitem__(self, key, 2 * value)
Run Code Online (Sandbox Code Playgroud)

例:

>>> m  = MyDict()
>>> m[0] = 5
>>> m
{0: 10}
Run Code Online (Sandbox Code Playgroud)

__setattr__ 控制对象属性本身(不是键/值对)的归属方式.


unu*_*tbu 8

子类化时要小心dict.如果你只是覆盖__setitem__,那么其他dict方法,如update,不会调用你的__setitem__.

class MyDict(dict):
    def __setitem__(self, key, value):
         dict.__setitem__(self, key, 2 * value)

d = MyDict()
d['first'] = 3
print(d['first'])
# 6

d.update({'first':4})
print(d['first'])
# 4                       # <--- __setitem__ was not called.
Run Code Online (Sandbox Code Playgroud)

为了创建类似dict的对象,您需要子类化dict并覆盖所有方法(请参阅OrderedDict以获取此方法的示例),或子类collections.MutableMapping并覆盖这些方法的小子集(从中派生所有其他方法) .

import collections

class MyDict2(collections.MutableMapping,dict):
    def __getitem__(self, key):
        return dict.__getitem__(self, key)
    def __setitem__(self, key, value):
         dict.__setitem__(self, key, 2 * value)
    def __delitem__(self, key):
        dict.__delitem__(self, key)
    def __iter__(self):
        return dict.__iter__(self)
    def __len__(self):
        return dict.__len__(self)
    def __contains__(self, x):
        return dict.__contains__(self, x)

d = MyDict2()
d['first'] = 3
print(d['first'])
# 6
d.update({'first':4})
print(d['first'])
# 8
Run Code Online (Sandbox Code Playgroud)