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

  • 相关阅读:
    删除datatable的重复行
    导出大Excel
    winform调用plugin
    System.AppDomain.CurrentDomain.BaseDirectory总是取得根目录
    能不能多想一点呢?
    执行语句使用exec (sql)
    open the folder
    取得一个表的所有字段
    快讯:麦考林第四季度净利110万美元同比减62%
    麦考林第四季度净利110万美元同比减62%(图解)
  • 原文地址:https://www.cnblogs.com/fuzzier/p/7855913.html
Copyright © 2011-2022 走看看