我从网上读到这个东西
对物体而言,机器在
object.__getattribute__其中转化b.x为type(b).__dict__['x'].__get__(b, type(b)).该实现通过优先级链工作,该优先级链 赋予数据描述符优先于实例变量,实例变量优先于非数据描述符,如果提供,则将最低优先级分配给getattr。
我不明白“赋予数据描述符优先于实例变量”和“实例变量优先于非数据描述符”是什么意思
谁能给我举个例子,这实际上是如何工作的?我想看看代码中有什么优先级
我从网上读到这个东西
对物体而言,机器在
object.__getattribute__其中转化b.x为type(b).__dict__['x'].__get__(b, type(b)).该实现通过优先级链工作,该优先级链 赋予数据描述符优先于实例变量,实例变量优先于非数据描述符,如果提供,则将最低优先级分配给getattr。
我不明白“赋予数据描述符优先于实例变量”和“实例变量优先于非数据描述符”是什么意思
谁能给我举个例子,这实际上是如何工作的?我想看看代码中有什么优先级
每个对象都有一个属性字典,其中包含它的变量和函数。参考这些词典:
If an instance’s dictionary has an entry with the same name as a data descriptor,
the data descriptor takes precedence. If an instance’s dictionary has an entry with
the same name as a non-data descriptor, the dictionary entry takes precedence.
这就是他们所说的。
要显示这一点:
#data descriptor
class A(object):
def __get__(self, obj, type):
print "hello from get A"
def __set__(self, obj, val):
print "hello from set A"
#non data descriptor
class B(object):
def __get__(self, obj, type):
print "hello from get B"
class C(object):
#our data descriptor
a = A()
#our non data descriptor
b = B()
>>> c = C()
>>> c.a
hello from get A
>>> c.b
hello from get B
>>> c.a = 0
hello from set A
>>> c.a #notice after reassignment, A.__get__ is still called
hello from set A
>>> c.b = 0 #instance variable with the same name as the non data-descriptor
>>> c.b #notice how B.__get__ isn't called anymore
0
基本上它是说当用户为对象(数据描述符)定义时,它们将被调用而不是默认方法__get__。__set__如果仅为__get__对象(非数据描述符)定义用户,则实例可以重新分配实例变量。
因此,当调用g.x = 0: 如果 x 是数据描述符,则调用 x 的用户定义__set__方法,当 x 是实例变量或非数据描述符时,调用默认行为。
使用数据描述符,该类控制对变量的所有访问和修改。所有对数据描述符类型变量的访问都将通过__get__和__set__。所以c.a = 0调用A.__set__和 ca 改变了类定义它的方式。无法创建不属于 A 类型的实例变量“ca”。
使用非数据描述符,该类仅控制访问,因此当c.b = 0被调用时,由于__set__未定义,因此会创建一个新的实例变量(默认行为)。设置变量时没有用户定义的行为,因此您可以创建一个具有相同名称的实例变量,而无需该__get__行为。
The precedence they are talking about is the dynamics of the two. A data descriptor will always call __get__ and __set__, and so an instance variable can't be created with the same name. A non data descriptor will only call __get__ until an instance variable with the same name is created.