python描述符相关和属性查找策略

描述符(descriptor)

描述符的作用是用来代理一个类的属性,需要注意的是描述符不能定义在类的构造函数中,只能定义为类的属性,它只属于类的,不属于实例,我们通过查看实例和类的字典即可知晓。

只要类重写任何下面的一个方法,类就被看作是descriptor,当这些descriptor在另外一个类中作为属性被访问时, 就可以不去采用默认的查找属性的顺序。

  • 1、__get__(self, instance, owner)
    获取属性时调用,返回设置的属性值,通常是set中的value,或者附加的其他组合值。

  • 2、__set__(self, instance, value)
    设置属性时调用,返回None.

  • 3、__delete__(self, instance)
    其中,instance是这个描述符属性所在的类的实体,而owner是描述符所在的类。

两种种类的描述符

数据描述符(data descriptor)和非数据描述符(non-data descriptors)

数据描述符:定义了setget方法的对象
非数据描述符:只定义了get方法的对象。

非数据描述符在python中

通常方法都是非数据描述符。比如后面会谈到的staticmethod,classmethod等。

此利用描述符的原理,我们完全可以自定义模拟@classmethod、@staticmethd、@property、等属性。实现这种类似系统的属性,我们还需要装饰器作为修饰 。

例如:(使用装饰器@的结果等价于将函数变为属性:)
声明非数据描述符descriptor_classmethod
@descriptor_classmethod,结合装饰器做成一个系统描述符。
参考


属性查找策略:

在Python中,属性查找(attribute lookup)是比较复杂的,特别是涉及到描述符descriptor的时候。

大致优先级如下:

__dict__属性 > 数据描述符 > 实例__dict__属性 > 非数据描述符 > 找不到的属性触发getattr()

通过实例。访问属性时,__getattribute__内部的搜索逻辑:

注意: 数据描述符永远是针对类来说的, 所以实例访问触发的__getattribute__第一步不会搜索实例obj的__dict__中attr是否data descriptor, 而是去搜索其类或其父/超类。

  • (1)如果“attr”是出现在类或其父/超类的__dict__中,检测attr是否data descriptor, 是则调用其get方法。
  • (2)如果“attr”出现在obj的__dict__中, 那么直接返回 obj.dict['attr']
  • (3)如果“attr”出现在类或其父/超类的__dict__中(这一步时attr已经不是data descriptor)
    (3.1)如果attr是non-data descriptor,那么调用其get方法, 否则
    (3.2)返回 dict['attr']
  • (4)如果类有getattr方法,调用getattr方法,否则
  • (5)抛出AttributeError
通过类名。访问属性时的搜索逻辑(不知道此时会不会调用getAttribute):
  • (1)如果“attr”是出现在类或其父/超类的__dict__中,优先返回“attr”
  • (2)如果“attr”是出现在类或其父/超类的__dict__中,是data descriptor,则调用其get方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章主要是对官方文档Python HOWTO之属性描述符的翻译。由于英语水平有限,基本上都是意译。 摘要 本篇...
    Syfun阅读 1,099评论 0 52
  • 简介 Python 中,一切皆对象。 当我们访问某个对象属性时,在不同的情况下,Python 对属性的访问机制有所...
    Whyn阅读 1,400评论 1 3
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 3,015评论 0 9
  • 1.对象的自省机制 自省是通过一定的机制查询到对象的内部结构 dir(obj) dir(obj)可以获取一个对象所...
    huxt阅读 223评论 0 0
  • 本文翻译自python descriptor guide 摘要 本文定义了描述符,总结了其中的协议,并且介绍如何调...
    大蟒传奇阅读 1,202评论 0 5