为什么我可以重新分配dict.update但不能重新分配dict .__ setitem__

时间:2019-03-26 01:09:00

标签: python

我正在尝试修改第三方dict类以使其在特定点后不可变。 对于大多数类,我可以分配给方法槽以修改行为。 但是,似乎并非所有类中的所有方法都可行。特别是对于dict,我可以重新分配update,但不能重新分配__setitem__

为什么?它们有什么不同?

例如:

class Freezable(object):
    def _not_modifiable(self, *args, **kw):
        raise NotImplementedError()

    def freeze(self):
        """
        Disallow mutating methods from now on.
        """
        print "FREEZE"
        self.__setitem__ = self._not_modifiable
        self.update = self._not_modifiable
        # ... others
        return self

class MyDict(dict, Freezable):
    pass

d = MyDict()
d.freeze()
print d.__setitem__  # <bound method MyDict._not_modifiable of {}>

d[2] = 3         # no error  -- this is incorrect.

d.update({4:5})  # raise NotImplementedError

1 个答案:

答案 0 :(得分:2)

请注意,您可以定义 __setitem__,例如:

def __setitem__(self, key, value):
    if self.update is Freezable._not_modifiable:
        raise TypeError('{} has been frozen'.format(id(self)))
    dict.__setitem__(self, key, value)

(此方法有点笨拙;还有其他选择。但是,即使Python直接调用类的__setitem__,它也是使它起作用的一种方法。)