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

问题描述:

我是从互联网如何在Python中的数据描述符的优先级工作

对于对象阅读这件事,机械是object.__getattribute__其中 转变b.xtype(b).__dict__['x'].__get__(b, type(b)).

实施工作通过优先链 给出数据描述符优先于实例变量实例变量优先于非数据描述符,并且分配如果提供的话,最低优先级为getattr

我不明白这是什么的“对非数据描述符实例变量优先”,“让数据描述符优先于实例变量”,平均

谁能给我例子,说明这实际上是我的工作想看看代码中有什么优先事物

+0

查看[@ blckknght's answer](http://*.com/a/14787522/4279)中的[相关问题]示例代码(http://*.com/q/14787334/4279) 。 – jfs 2013-02-10 11:32:30

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

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被改变为类如何定义它。没有方法来创建实例变量“CA”是类型A.

随着非数据描述符的否,类只控制接入,所以当c.b = 0被调用时,因为__set__没有定义,会创建一个新的实例变量(默认行为)。在设置变量时没有用户定义的行为,因此您可以创建一个具有相同名称的实例变量,而不需要执行__get__行为。

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

+0

我再次不清楚。你说过如果'x是数据描述符',所以它意味着如果x没有定义'__get__'和'__set__'。对?所以它意味着x将永远是一个类,因为我只能在类中定义方法。如果'x'是实例变量,那么我怎样才能定义像'__get__'这样的方法在变量中。这让我很困惑 – user196264097 2013-02-10 14:28:45

+0

是的,数据描述符的定义是它定义了'__get__'和'__set__'。非数据描述符只定义了__get__。一个实例变量可以是一个类的对象,所以就像'c.a = MyClass()'。它更多的是关于数据描述符用户如何使用__set__定义修改,以及非数据描述符如何不用用户定义修改。我编辑以尝试提高清晰度。 – Raufio 2013-02-10 19:20:53

+0

注意:具有'__slots__'属性的类的对象没有属性字典。 – jfs 2013-02-11 02:40:46