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

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

def __call__(self, proxy):
    """Create a proxy for a name."""
    return LocalProxy(self, proxy)

def __getattr__(self, name):
    try:
        return self.__storage__[self.__ident_func__()][name]
    except KeyError:
        raise AttributeError(name)

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

def __delattr__(self, name):
    try:
        del self.__storage__[self.__ident_func__()][name]
    except KeyError:
        raise AttributeError(name)

I want to know the difference between __setattr__ magic function and self.__xxx__ = {}. Now I put more code here.In the constructor,it's object.setattr.So does the overwritten have some influence to it ?

陈飞坤
  • 1
  • 1
  • Is that the entire class? It’s calling `object.__setattr__`, so `Local` could have its own overridden `__setattr__`. – Ry- Jul 09 '18 at 03:40
  • Does your class have an override of `__setattr__` elsewhere? Otherwise, I'm pretty sure either version is equivalent (the version that avoids `object.__setattr__` being better, but still poor form, since [names beginning and ending with `__` are reserved for the language](https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers)). – ShadowRanger Jul 09 '18 at 03:42
  • @Mr.J: Though those uses are needed for avoiding infinite recursion when implementing `__setattr__` itself. Not typically needed for `__init__`. – ShadowRanger Jul 09 '18 at 03:45
  • @ShadowRanger fat finger :) – jits_on_moon Jul 09 '18 at 03:48
  • .In the constructor,it's object.setattr.So does the overwritten have some influence to it ? – 陈飞坤 Jul 09 '18 at 05:42

1 Answers1

0

Like almost all __...__ classes, __setattr__ is basically designed to be overridden in inheriting classes to change how a Python class works. If changing the semantics of x.foo wasn't needed, __setattr__ might not exist. x.foo is defined as __setattr__ on self; so it could do anything (e.g. set up DB fields like in Django).

But notice that the code in the question calls object.__setattr__, not the one on self. Thus, even if the current class overrides __setattr__ to do something completely different, you can still use object's definition of the original attribute-setting behaviour to... set an attribute.

Amadan
  • 191,408
  • 23
  • 240
  • 301