问一个__setattr__和__set__优先级的问题

2017-09-26 22:51:53 +08:00
 chenstack

测试代码

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__的优先级更高?求告知。

3141 次点击
所在节点    Python
7 条回复
guyskk0x0
2017-09-26 23:01:09 +08:00
获取不存在的属性时才会调用 __getattr__
chenstack
2017-09-26 23:12:04 +08:00
@guyskk0x0 这个知道,主要想问,比如上面调用 a.p = 1 和 del a.p 时,描述器的__set__和__delete__为什么没有被调用,注释掉__setattr__和__delattr__后就会被调用。
lrxiao
2017-09-27 02:12:20 +08:00
我感觉是命名失误..

和__setattr__对标的应该是__getattribute__ 因为只有 get 情况才需要考虑是否存在
lrxiao
2017-09-27 02:15:41 +08:00
所以有了__getattr__
mapleray
2017-09-27 09:53:33 +08:00
http://python.jobbole.com/88582/ 可以参考下这篇文章
laike9m
2017-09-27 10:57:28 +08:00
这个是个好问题。。同意 @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
chenstack
2017-09-27 12:50:10 +08:00
@lrxiao @mapleray 感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/393900

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX