python descriptor override

本文深入探讨了Python中描述符的工作原理,包括其在新式对象和类上的行为,以及如何通过直接调用、实例绑定、类绑定和超绑定进行触发。重点解释了数据描述符和非数据描述符的区别,以及它们如何影响属性访问的行为。

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

.4.2.3 Invoking Descriptors

In general, a descriptor is an object attribute with ``binding behavior'', one whose attribute access has been overridden by methods in the descriptor protocol: __get__()__set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.

The default behavior for attribute access is to get, set, or delete the attribute from an object's dictionary. For instance, a.x has a lookup chain starting with a.__dict__['x'], then type(a).__dict__['x'], and continuing through the base classes of type(a) excluding metaclasses.

However, if the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined and how they were called. Note that descriptors are only invoked for new style objects or classes (ones that subclass object() or type()).

The starting point for descriptor invocation is a binding, a.x. How the arguments are assembled depends on a:

Direct Call
The simplest and least common call is when user code directly invokes a descriptor method:  x.__get__(a).

Instance Binding
If binding to a new-style object instance,  a.x is transformed into the call:  type(a).__dict__['x'].__get__(a, type(a)).

Class Binding
If binding to a new-style class,  A.x is transformed into the call:  A.__dict__['x'].__get__(None, A).

Super Binding
If  a is an instance of  super, then the binding  super(B, obj).m() searches  obj.__class__.__mro__ for the base class  A immediately preceding  B and then invokes the descriptor with the call:  A.__dict__['m'].__get__(obj, A).

For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. Data descriptors define both __get__() and __set__(). Non-data descriptors have just the __get__()method. Data descriptors always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances.

Python methods (including staticmethod() and classmethod()) are implemented as non-data descriptors. Accordingly, instances can redefine and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class.

The property() function is implemented as a data descriptor. Accordingly, instances cannot override the behavior of a property.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值