• Python descriptor and attribute lookup order


    1.1(ref:http://hbprotoss.github.io/posts/python-descriptor.html)首先介绍下__dict__

    举例:

    class A(object):
        a_g = 1
        def __init__(self, a_l):
            self._a_l = a_l
        def foo(self):
            pass

    print A.__dict__

    a = A(5)
    print a.__dict__

    输出如下:

    { '__module__': '__main__',
       'a_g': 1, 
       '__dict__': <attribute '__dict__' of 'A' objects>, 
       'foo': <function foo at 0x10bdfb668>,
       '__weakref__': <attribute '__weakref__' of 'A' objects>,
       '__doc__': None,
       '__init__': <function __init__ at 0x10bdfb050>
    }
    
    {'_a_l': 5}

    可以看到,A包含所有方法和类全局的变量(这些方法也可以看成全局的),

    A(5)只包含初始化的时候传入的变量(__init__里self.xx那一类属性)

    1.2 实例中不包含类的方法,但是我们在调用a.foo()的时候,却能够找到正确的方法,这是为什么呢?

    >> a.foo

    <bound method A.foo of <__main__.A object at 0x1094504d0>>

    >> A.__dict__['foo']

    <function foo at 0x10944d668>

    >>> A.__dict__['foo'].__get__(a, A)
    <bound method A.foo of <__main__.A object at 0x1094504d0>>

    当从a中获取foo属性的时候,是遵循一定的顺序的。这取决于foo是哪个类的对象。

    这里引入descriptor的概念:

    一个descriptor实际上是一个特殊的类的对象。

    如果这个类同时定义了__get__和__set__方法,那么这个类的对象叫data descriptor。 

    如果这个类只定义了__get__方法,那么这个类的对象叫non-data descriptor

    假如一个descriptor a_d作为一个类A的属性,那么当A的对象a访问a_d的时候,会调用a_d的__get__, __set__方法

    实际上,A.__dict__['foo']实际上是一个descriptor,当我们a.foo的时候,实际上是调用了这个descriptor的__get__方法。

    1.3 (ref:http://www.cnblogs.com/xybaby/p/6270551.html)

     实例属性查找的顺序为:

        obj = Clz(), 那么obj.attr(等价于obj.attr) 顺序如下:

        (1)如果“attr”是出现在Clz或其基类的__dict__中, 且attr是data descriptor, 那么调用其__get__方法, 否则

        (2)如果“attr”出现在obj的__dict__中, 那么直接返回 obj.__dict__['attr'], 否则

        (3)如果“attr”出现在Clz或其基类的__dict__中

            (3.1)如果attr是non-data descriptor,那么调用其__get__方法, 否则

            (3.2)返回 __dict__['attr']

        (4)如果Clz有__getattribute__方法,调用__getattribute__方法,如果抛出AttributeError,则继续调用

    __getattr__。否则抛出AttributeError结束。

  • 相关阅读:
    使用AudioRecord录音
    使用MediaRecorder录音
    程序员不应迷失方向
    鼠标移入下划线展开 CSS3伪类
    横向滚动条,鼠标按下左右滚动!
    js遍历数组的几种方法
    前端随心记---------nodejs工具nvm.nrm.nodemen
    前端随心记-----------面试题分享
    鹅厂前端面试小题
    前端随心记-------浅谈Axios
  • 原文地址:https://www.cnblogs.com/geeklove01/p/9021712.html
Copyright © 2020-2023  润新知