数据描述符优先级如何在python中工作

时间:2013-02-10 08:08:34

标签: python

我正在从互联网上读这件事

  

对于物体,机器在object.__getattribute__中   将b.x转换为type(b).__dict__['x'].__get__(b, type(b)).

     

实现通过优先级链工作   使数据描述符优先于实例变量实例变量优先于非数据描述符,并将最低优先级分配给 getattr (如果提供)。

我不明白“给数据描述符优先于实例变量”和“实例变量优先级高于非数据描述符”是什么意思

任何人都可以举例说明这实际上是如何工作的,我想看看代码中有什么东西是

1 个答案:

答案 0 :(得分:5)

每个对象都有一个属性字典,其中包含变量和函数。参考这些词典:

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__并更改了c.a如何定义它。无法创建不属于A类型的实例变量“c.a”。

使用非数据描述符,该类仅控制访问,因此在调用c.b = 0时,由于未定义__set__,因此会生成新的实例变量(默认行为)。设置变量时没有用户定义的行为,因此您可以创建具有相同名称的实例变量,而不会出现__get__行为。

他们谈论的优先事项是两者的动态。数据描述符将始终调用__get____set__,因此无法使用相同名称创建实例变量。非数据描述符只会调用__get__,直到创建具有相同名称的实例变量。