python属性访问优先级

1 属性访问优先级为

  1 __getattribute__(), 入口

  2 数据描述符

  3 实例对象的字典 obj.__dict__ (若与描述符同对象名,会被覆盖) 

  4 类的字典 Class.__dict__ 

  5 非数据描述符

  6 父类的字典

  7 __getattr__() 

 

2 调用流程

假设我们有个 类A ,其中 a是A的实例
当调用 a.x  时候属性访问顺序如下:

  0 __getattribuite__ 为入口

  1 如果重载了 __getattribute__ ,则调用.

  2 如果遇到 数据型 descriptor 会覆盖 a.__dict__ 优先调用 a.__class__.__dict__ 的 数据型 descriptor

  3 a.__dict__ , 实例中是不允许有 descriptor 的,所以不会遇到descriptor

  4 A.__dict__ , 也即 a.__class__.__dict__  .

  5 如果遇到了 非数据型descriptor ,则会在搜索父类属性前优先调用

  6 沿着继承链搜索父类.搜索 a.__class__.__bases__ 中的所有 __dict__ . 如果有多重继承且是菱形继承的情况,按 MRO(Method Resolution Order) 顺序搜索.

  7 如果以上都搜不到, 就会触发 a.__getattr__, 则抛 AttributeError 异常.

 

3 实际示例

class Des(object):
    def __init__(self, name):
        # 第二步,描述符对象初始化
        self.name = name
        print("__init__(): name = ", self.name)

    # 第十步 调用描述符Des的__get__方法
    def __get__(self, instance, owner):
        print("__get__() ...")
        return self.name

    # 第六步 实例f._x = x时调用完__setter__后调用__set__
    def __set__(self, instance, value):
        print 'im set'
        print value
        print 'set over'


class Foo(object):
    # 第一步 创建描述符对象
    # 第九步 因为 Foo._x 为数据型描述符,所以覆盖掉对象f._x
    _x = Des('wwt')

    temp = 'im temp'

    # 第四步 初始化实例f
    def __init__(self, x):
        self._x = x

    # 第八步 先会访问更改后的__getattribute__方法
    def __getattribute__(self, item):
        print 'im getattribute'
        return super(Foo, self).__getattribute__(item)

    # 第五步 实例f._x = x时调用__setattr__
    def __setattr__(self, key, value):
        print 'im setter'
        return super(Foo, self).__setattr__(key, value)


# 第三步 创建Foo对象f
f = Foo(10)
# 第七步 对象f属性获取
print f._x  # 因为对象f._x被Foo._x的描述符覆盖,所以返回为 wwt

 

'''
out:
('__init__(): name = ', 'wwt')
im setter
im set
10
set over
im getattribute
__get__() ...
wwt
'''

 

 

 

本文参考

Jimmy_Nie 的文章,地址为 http://www.cnblogs.com/Jimmy1988/p/6808237.html

 luozhaoyu 的文章, 地址 http://www.jb51.net/article/86749.htm

 

转载于:https://www.cnblogs.com/fuzzier/p/7855913.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值