`object .__ setattr __ (self, ..., ...)` instead of `setattr (self, ..., ...)`?

The following is the __init__ method of the Local class from the werkzeug library:

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

I do not understand two things about this code:

  • Why do they write

     object.__setattr__(self, '__storage__', {}) 

    instead of simple

     `setattr(self, '__storage__', {})` 
  • Why did they even use __setattr__ if they just wrote

     self.__storage__ = {} 
+5
source share
3 answers

This ensures that the default Python definition is __setattr__ . It is usually used if the class has overridden __setattr__ to perform custom behavior, but you still want to access the original __setattr__ behavior.

In the case of werkzeug, if you look at the Local class, you will see that __setattr__ is defined as follows:

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

Instead of setting attributes in the dictionary of an object, it sets them in the dictionary __storage__ , which was initialized earlier. To set the __storage__ attribute __storage__ general (so that it can be accessed, for example, self.__storage__ later), the original __setattr__ definition from the object must be used, so the constructor uses an inconvenient notation.

+6
source

They want to explicitly use the base implementation of object.__setattr__ instead of a possible overridden method of the method instance somewhere else in the inheritance chain. Local implements its own __setattr__ , so this avoids this.

+2
source

Since the same class defines __setattr__ , and you need to get around this, since the first line says self.__ident_func__() , which does not work yet.

+1
source

Source: https://habr.com/ru/post/1233365/


All Articles