python属性访问优先级

Posted fuzzier

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于python属性访问优先级的主要内容,如果未能解决你的问题,请参考以下文章

在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途

Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联

关于CSS的个人理解

Python snippet(代码片段)

深度优先和广度优先算法

30 段 Python 实用代码