Podklasowanie słownika Pythona w celu zastąpienia __setitem__

Buduję klasę, której podklasydicti nadpisania__setitem__. Chciałbym mieć pewność, że moja metoda zostanie wywołana we wszystkich przypadkach, w których elementy słownika mogłyby być ustawione.

Odkryłem trzy sytuacje, w których Python (w tym przypadku 2.6.4) nie wywołuje mojego przesłonięcia__setitem__ metoda podczas ustawiania wartości, a zamiast tego wywołujePyDict_SetItem bezpośrednio

W konstruktorzewsetdefault metodawupdate metoda

Jako bardzo prosty test:

class MyDict(dict):
    def __setitem__(self, key, value):
        print "Here"
        super(MyDict, self).__setitem__(key, str(value).upper())

>>> a = MyDict(abc=123)
>>> a['def'] = 234
Here
>>> a.update({'ghi': 345})
>>> a.setdefault('jkl', 456)
456
>>> print a
{'jkl': 456, 'abc': 123, 'ghi': 345, 'def': '234'}

Widać, że nadpisana metoda jest wywoływana tylko podczas jawnego ustawiania elementów. Aby Python zawsze dzwonił do mojego__setitem__ metody, musiałem ponownie zaimplementować te trzy metody, takie jak ta:

class MyUpdateDict(dict):
    def __init__(self, *args, **kwargs):
        self.update(*args, **kwargs)

    def __setitem__(self, key, value):
        print "Here"
        super(MyUpdateDict, self).__setitem__(key, value)

    def update(self, *args, **kwargs):
        if args:
            if len(args) > 1:
                raise TypeError("update expected at most 1 arguments, got %d" % len(args))
            other = dict(args[0])
            for key in other:
                self[key] = other[key]
        for key in kwargs:
            self[key] = kwargs[key]

    def setdefault(self, key, value=None):
        if key not in self:
            self[key] = value
        return self[key]

Czy są jakieś inne metody, które muszę przesłonić, aby wiedzieć, że Python to zrobizawsze Zadzwoń do mojego__setitem__ metoda?

AKTUALIZACJA

Zgodnie z sugestią gs próbowałem podklasowania UserDict (właściwie IterableUserDict, ponieważ chcę iterować po kluczach) w ten sposób:

from UserDict import *;
class MyUserDict(IterableUserDict):
    def __init__(self, *args, **kwargs):
        UserDict.__init__(self,*args,**kwargs)

    def __setitem__(self, key, value):
        print "Here"
        UserDict.__setitem__(self,key, value)

Ta klasa wydaje się poprawnie nazywać moją__setitem__ nasetdefault, ale to się nie nazywaupdatelub gdy dane wstępne są dostarczane do konstruktora.

AKTUALIZACJA 2

Sugestia Petera Hansena skłoniła mnie do uważniejszego przyjrzenia się dictobject.c i zdałem sobie sprawę, że metoda aktualizacji może być nieco uproszczona, ponieważ wbudowany konstruktor słownika po prostu wywołuje wbudowaną metodę aktualizacji. Wygląda teraz tak:

def update(self, *args, **kwargs):
    if len(args) > 1:
        raise TypeError("update expected at most 1 arguments, got %d" % len(args))
    other = dict(*args, **kwargs)
    for key in other:
        self[key] = other[key]

questionAnswers(4)

yourAnswerToTheQuestion