Подкласс Python словарь для переопределения __setitem__

Я строю класс, который подклассыdictи переопределяет__setitem__, Я хотел бы быть уверен, что мой метод будет вызываться во всех случаях, когда элементы словаря могут быть установлены.

Я обнаружил три ситуации, когда Python (в данном случае 2.6.4) не вызывает мой переопределенный__setitem__ метод при установке значений, а вместо этого вызываетPyDict_SetItem непосредственно

В конструкторевsetdefault методвupdate метод

Как очень простой тест:

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'}

Вы можете видеть, что переопределенный метод вызывается только при явной установке элементов. Чтобы Python всегда вызывал мой__setitem__ метод, мне пришлось переопределить эти три метода, как это:

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]

Есть ли другие методы, которые мне нужно переопределить, чтобы знать, что Python будетвсегда позвони мне__setitem__ метод?

ОБНОВИТЬ

Согласно предложению gs, я попытался создать подкласс UserDict (на самом деле, IterableUserDict, поскольку я хочу перебирать ключи) следующим образом:

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)

Этот класс, кажется, правильно называть мой__setitem__ наsetdefault, но это не вызываетupdateили когда начальные данные передаются в конструктор.

ОБНОВЛЕНИЕ 2

Предложение Питера Хансена заставило меня более внимательно посмотреть на dictobject.c, и я понял, что метод обновления можно немного упростить, так как встроенный конструктор словаря просто вызывает встроенный метод обновления в любом случае. Теперь это выглядит так:

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]

Ответы на вопрос(4)

Ваш ответ на вопрос