测试代码
class P(object):
def __get__(self, obj, type):
return '__get__'
def __set__(self, name, value):
print('__set__')
def __delete__(self, name):
print('__delete__')
class A(object):
p = P()
def __getattr__(self, name):
return '__getattr__'
def __setattr__(self, name, value):
print('__setattr__')
def __delattr__(self, name):
print('__delattr__')
a = A()
print(a.p)
a.p = 1
del a.p
结果分别是 __get__, __setattr__, __delattr__
经过测试,__get__优先级大于__getattr__,而__setattr__大于__set__, __delattr__大于__delete__。
猜测是 descriptor 是由 object 的__getattribute__调用的,不管 data descriptor 还是 non-data like descriptor,在实例上调用同名的属性,__get__先于__getattr__。
但不太明白__setattr__和__delattr__优先级为何更大,这样设计的目的是什么?实现上是 object 的__setattr__里面根据情况调用描述器的__set__,所以实例__setattr__的优先级更高?求告知。
1
guyskk0x0 2017-09-26 23:01:09 +08:00 via Android
获取不存在的属性时才会调用 __getattr__
|
2
chenstack OP @guyskk0x0 这个知道,主要想问,比如上面调用 a.p = 1 和 del a.p 时,描述器的__set__和__delete__为什么没有被调用,注释掉__setattr__和__delattr__后就会被调用。
|
3
lrxiao 2017-09-27 02:12:20 +08:00
我感觉是命名失误..
和__setattr__对标的应该是__getattribute__ 因为只有 get 情况才需要考虑是否存在 |
4
lrxiao 2017-09-27 02:15:41 +08:00
所以有了__getattr__
|
5
mapleray 2017-09-27 09:53:33 +08:00
http://python.jobbole.com/88582/ 可以参考下这篇文章
|
6
laike9m 2017-09-27 10:57:28 +08:00 1
这个是个好问题。。同意 @lrxiao 说的命名失误
The search order that Python uses for attributes goes like this: 1. __getattribute__ and __setattr__ 2. Data descriptors, like property 3. Instance variables from the object's __dict__ (when setting an attribute, the search ends here) 4. Non-Data descriptors (like methods) and other class variables 5. __getattr__ 来源: https://stackoverflow.com/questions/15750522/class-properties-and-setattr |