Python descriptor 描述器

本文详细介绍了Python中描述符的概念及其实现原理。包括描述符协议(__get__,__set__,__delete__),数据描述符与非数据描述符的区别,以及如何通过重写默认行为来自定义描述符。此外还解释了描述符在新式类中的使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Descriptor HowTo Guide

概述介绍

python descriptor 包含了自定义的descriptor, 和built-in python descriptors 包含了函数,属性(properties),静态方法,类方法.

通常,一个descriptor是一个实例对象的绑定方法”binding behavior”, 他们的这些特性(attribute)可以通过descriptor协议来重写.这些方法为 __get__(), __set__(),__delete__().如果上述任何一个方法都被实例对象显式的定义,就可以称之为descriptor

对于默认的上述方法,则是对于实例对象(object)的字典进行get,set,delete操作.

例如: 执行a.x时,会进行一系列的操作:

  • 首先 a.__dict__['x']
  • 然后继续通过type(a),除了元类
  • 当发现type(a)的基类定义了其中一种descriptor方法之后
  • Python将会重写默认的方法,调用(invoke) descriptor方法

注意: 只有新式的对象或者类才能调用descriptor方法
(继承自object或者type的类是新式的类)

Descriptor Protocol(描述器协议)

descr.__get__(self, obj, type=None) -->value
descr.__set__(self, obj, value) -->Node
descr.__delete__(self,obj)

定义了任意一个方法的对象,都可以被称为一个descriptor并且重写默认的行为.

当一个对象同时定义了__get__(),__set__(),可以认为它是一个数据描述器(data descriptor),如果仅仅定义了__get__(),则它为非数据描述前(non-data descriptor)

数据描述器和非数据描述器不同在于如何重写进入实例字典的方法.

如果实例字典的入口函数名和数据描述器一样,则数据描述器优先;如果实例字典的入口函数名和非数据描述器一样,则字典入口函数优先

为了定义只读数据描述器则可以,定义__get__() ,__set()__ , 同时当__set()__函数调用时,抛出一个AttributeError的错误

Invoking Descriptors(调用描述器)

描述器可以直接的调用名字,`d.get(obj).更普遍的一种方法是,通过特性方法进行自动的调用

object.__getattribute__() 可以使 b.x 变为
type(b).__dict__['x'].__get__(b,type(b)).
这种实现方法的优先级顺序为:

  1. data descriptors
  2. instance variables
  3. non-data descriptors
  4. 最低的优先级 __getattr__() (如果提供了)

重要的点:

  • descriptors 可以被 __getattribute__()方法调用
  • 重写__getattribute__()阻止了desciptors的自动调用
  • __getattribute__()只有新式类可用
  • object.__getattribute__()type.__getattribute__()对于调用__get__不同

Reference

python2.7 doc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值