如何在Python中的数据描述符的优先级工作
我是从互联网如何在Python中的数据描述符的优先级工作
对于对象阅读这件事,机械是
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__
,并且c.a被改变为类如何定义它。没有方法来创建实例变量“CA”是类型A.
随着非数据描述符的否,类只控制接入,所以当c.b = 0
被调用时,因为__set__
没有定义,会创建一个新的实例变量(默认行为)。在设置变量时没有用户定义的行为,因此您可以创建一个具有相同名称的实例变量,而不需要执行__get__
行为。
他们谈论的优先顺序是两者的动态。数据描述符将始终调用__get__
和__set__
,因此不能使用相同的名称创建实例变量。非数据描述符只会调用__get__
,直到创建一个具有相同名称的实例变量。
我再次不清楚。你说过如果'x是数据描述符',所以它意味着如果x没有定义'__get__'和'__set__'。对?所以它意味着x将永远是一个类,因为我只能在类中定义方法。如果'x'是实例变量,那么我怎样才能定义像'__get__'这样的方法在变量中。这让我很困惑 – user196264097 2013-02-10 14:28:45
是的,数据描述符的定义是它定义了'__get__'和'__set__'。非数据描述符只定义了__get__。一个实例变量可以是一个类的对象,所以就像'c.a = MyClass()'。它更多的是关于数据描述符用户如何使用__set__定义修改,以及非数据描述符如何不用用户定义修改。我编辑以尝试提高清晰度。 – Raufio 2013-02-10 19:20:53
注意:具有'__slots__'属性的类的对象没有属性字典。 – jfs 2013-02-11 02:40:46
查看[@ blckknght's answer](http://*.com/a/14787522/4279)中的[相关问题]示例代码(http://*.com/q/14787334/4279) 。 – jfs 2013-02-10 11:32:30