Search code examples
pythonflaskwerkzeug

Is there any difference between object.__setattr__() and directly set?


In werkzeug, we see:

class Local(object):
    __slots__ = ('__storage__', '__ident_func__')

    def __init__(self):
        object.__setattr__(self, '__storage__', {})

So, may I use self.__storage__ = {} to replace object.__setattr__(self, '__storage__', {}), and why?


Solution

  • The same class defines a custom __setattr__ method that stores values in self.__storage__:

    def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}
    

    However, you first need to set an initial empty dictionary, so the object.__setattr__ method is used to bypass the custom one.

    If you were to use self.__storage__ = {} then the above custom method would be called and that would lead to an attribute error, as self.__storage__ doesn't exist yet. Or rather, it'd lead to an infinite recursion issue, as the custom __getattr__ method would repeatedly be called to resolve the missing __storage__ attribute.