问题
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 don't understand two things about this code:
Why did they write
object.__setattr__(self, '__storage__', {})instead of simply
`setattr(self, '__storage__', {})`Why did they even use
__setattr__if the could simply writeself.__storage__ = {}
回答1:
This ensures that the default Python definition of __setattr__ is used. It's generally used if the class has overridden __setattr__ to perform non-standard behaviour, but you still wish to access the original __setattr__ behaviour.
In the case of werkzeug, if you look at the Local class you'll see __setattr__ is defined like this:
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 the object, it sets them in the __storage__ dictionary that was initialized previously. In order to set the __storage__ attribute at all (so that it may be accessed like self.__storage__ later), the original definition of __setattr__ from object must be used, which is why the awkward notation is used in the constructor.
回答2:
They want to explicitly use the base object.__setattr__ implementation instead of a possibly overridden method instance method somewhere else in the inheritance chain. Local implements its own __setattr__ so this avoids that.
回答3:
Because the same class defines __setattr__ and this needs to bypass that, since the first line says self.__ident_func__() which wouldn't work yet.
来源:https://stackoverflow.com/questions/33041518/object-setattr-self-instead-of-setattrself