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
,因此避免了这种情况。我要补充的是,尽管它在源代码中看起来很笨拙,但它为类的用户提供了一个很好的界面。