zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Linux 共享库
    使用Visual Studio(VS)开发Qt程序代码提示功能的实现(转)
    ZOJ 3469 Food Delivery(区间DP)
    POJ 2955 Brackets (区间DP)
    HDU 3555 Bomb(数位DP)
    HDU 2089 不要62(数位DP)
    UESTC 1307 windy数(数位DP)
    HDU 4352 XHXJ's LIS(数位DP)
    POJ 3252 Round Numbers(数位DP)
    HDU 2476 String painter (区间DP)
  • 原文地址:https://www.cnblogs.com/fuzzier/p/7855913.html
Copyright © 2011-2022 走看看