2

The following code does not behave as I expected with Python 3.4.2:

>>> from collections import UserDict
>>> class freezable_dict(UserDict):
    def freeze(self):
        def __setitem__(*args):   # (self, *args) behaves the same
            '''custom __setitem__'''
            raise TypeError
        self.__setitem__ = __setitem__

>>> f=freezable_dict()
>>> f[0]=42
>>> help(f.__setitem__)
Help on method __setitem__ in module collections:

__setitem__(key, item) method of __main__.freezable_dict instance

>>> f.freeze()
>>> help(f.__setitem__)
Help on function __setitem__ in module __main__:

__setitem__(*args)
    custom __setitem__

>>> f[1]=42
>>> f
{0: 42, 1: 42}
>>> 

After calling the freeze method, help(f.__setitem__) shows the expected docstring. But, the function I rebound the special method name to is not what is called by f[1]=42. I would have expected the attempt to add a new item to f after invoking f.freeze to raise a TypeError. Why doesn't it?

(I'm actually interested here in why my code doesn't work as I expected. But, the motivation is that I want to populate a dict-like thing and, once it is initially populated, lock it down against further changes. Had my code here worked, I would have gone on to have the freeze method also rebind __delitem__.)

vanden
  • 391
  • 1
  • 2
  • 11

0 Answers0