我是从网上读这个东西的
对于物体,机器在
object.__getattribute__其中转变b.x为type(b).__dict__['x'].__get__(b, type(b)).实现通过优先级链工作,该优先级链 使数据描述符优先于实例变量,实例变量优先于非数据描述符,并且如果提供则为getattr分配最低优先级.
我不明白"给数据描述符优先于实例变量"和"实例变量优先于非数据描述符"是什么意思
任何人都可以给我举例说明这实际上是如何工作的我想看看代码中有什么东西是priorty
每个对象都有一个属性字典,其中包含变量和函数.参考这些词典:
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.
Run Code Online (Sandbox Code Playgroud)
这就是他们所说的.
为了表明这一点:
#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
Run Code Online (Sandbox Code Playgroud)
基本上,它是说,当__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__行为.
他们谈论的优先事项是两者的动态.数据描述符总是会调用__get__和__set__,因此一个实例变量不能使用相同的名称创建.非数据描述符将仅__get__在创建具有相同名称的实例变量之前调用.
| 归档时间: |
|
| 查看次数: |
609 次 |
| 最近记录: |