【发布时间】:2017-12-09 19:28:03
【问题描述】:
Python in a Nutshell 描述了the lookup procedure when getting an attribute from a class, e.g. cls.name and the lookup procedure when getting an attribute from an instance, e.g. obj.name
但我不确定何时设置属性:
设置属性
请注意,属性查找步骤仅按照刚才的描述发生 当您引用一个属性时,而不是当您绑定一个属性时。什么时候 您绑定(在类或实例上)名称为 不是特别的(除非
__setattr__方法,或__set__重写描述符的方法,拦截绑定 实例属性),您只影响__dict__条目 属性(分别在类或实例中)。换一种说法, 对于属性绑定,不涉及查找过程,除了 用于检查覆盖描述符。
我的问题是:
从类中设置属性时的“查找”过程是什么,例如
cls.name=value?从对象设置属性时的“查找”过程是什么,例如
obj.name=value?
程序似乎涉及
-
__setattr__方法__setattr__(self, name, value)
在每次请求绑定属性
x.y(通常是一个赋值语句x.y=value,还有,例如,setattr(x, 'y', value)),Python 调用x.__setattr__('y', value)。 Python 总是调用__setattr__x 上的属性绑定——与__getattr__的主要区别(__setattr__是 在这个意义上更接近__getattribute__)。为了避免递归,当x.__setattr__绑定x的属性,必须直接修改x.__dict__(例如, 通过x.__dict__[name]=value);更好的是,__setattr__可以委托 设置为超类(通过调用super(C, x).__setattr__('y', value)或者,在 v3 中,只是super().__setattr__('y', value))。 Python 忽略__setattr__的返回值。如果__setattr__不存在(即,继承自object),而C.y不是覆盖描述符,Python 通常会翻译x.y=z进入x.__dict__['y']=z。 覆盖描述符的
__set__方法(所以我问Why does `object.__get__` have an argument `owner` for the owner class, while `object.__set__` doesn't?)- 属性的
__dict__条目(分别在类或实例中)
Given that the book distinguishes the lookup procedures for getting an attribute from a class and from an instance,很自然地认为从类设置属性和从实例设置属性时“查找”过程是不同的。
但是由于在 Python3 中,每个类对象实际上都是其元类的一个实例(例如 type 类),因此是用于从类中设置属性的“查找”过程和用于从类中设置属性的“查找”过程一个真正不同的实例?
谢谢。
【问题讨论】:
-
非常简单:它分配给该类的属性。它不会进入基类。
-
书中的引述似乎没有那么简单。
-
@Tim 您的问题在第二个引用的最后一句中得到了回答:“换句话说,对于属性绑定,除了检查覆盖描述符之外,不涉及查找过程。 ".
-
我不确定我是否理解那句话,并且我认为那句话不能代替整个段落,因为该段落暗示仍有一些“查找”程序,而那句话也错过了@987654356 @ 段落中的方法。 @ChristianDean
-
@Tim “你只影响属性的
__dict__条目”有什么复杂之处?
标签: python python-3.x