Python `对象。uuu setattr_uuuu(self,…)`而不是` setattr(self,…)`?

Python `对象。uuu setattr_uuuu(self,…)`而不是` setattr(self,…)`?,python,class,methods,Python,Class,Methods,以下是来自werkzeug库的Local类的\uuuuuu init\uuuuuuu方法: def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) 关于此代码,我不了解两件事: 他们为什么写作 object.__setattr__(self, '__storage__', {}) 而不是简单地 `s

以下是来自
werkzeug
库的
Local
类的
\uuuuuu init\uuuuuuu
方法:

def __init__(self):
    object.__setattr__(self, '__storage__', {})
    object.__setattr__(self, '__ident_func__', get_ident)
关于此代码,我不了解两件事:

  • 他们为什么写作

    object.__setattr__(self, '__storage__', {})
    
    而不是简单地

    `setattr(self, '__storage__', {})`
    
  • 为什么他们甚至使用
    \uuuuu setattr\uuuuu
    ,如果他们可以简单地编写

    self.__storage__ = {}
    

  • 因为同一个类定义了
    \uuuuu setattr\uuuuu
    ,而这需要绕过它,因为第一行说的是
    self.\uu ident\u func\uuuuu()
    ,这还不起作用。

    这确保使用了
    \uuuu setattr\uuuu
    的默认Python定义。如果类已重写
    \uuuuu setattr\uuuu
    以执行非标准行为,但您仍希望访问原始的
    \uuuuuuu setattr\uuuuu
    行为,则通常使用它

    在werkzeug的情况下,如果您查看
    本地
    类,您将看到
    \uuuuu setattr\uuuuuuu
    的定义如下:

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

    它不是在对象的字典中设置属性,而是在先前初始化的
    \uuu存储\uuuu
    字典中设置属性。为了设置
    \uuuuu storage\uuuuuu
    属性(以便以后可以像
    self.\uuuuu storage\uuuuu
    一样访问该属性),必须使用来自对象的
    \uuuuuuu setattr\uuuuuu
    的原始定义,这就是在构造函数中使用笨拙符号的原因。

    他们希望显式使用基本
    对象。\uuuu setattr\uuuu
    实现,而不是继承链中其他地方可能重写的方法实例方法
    Local
    实现了自己的
    \uuuu setattr\uuuu
    ,因此避免了这种情况。

    我要补充的是,尽管它在源代码中看起来很笨拙,但它为类的用户提供了一个很好的界面。