You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何functools.cached_property无需__new__/__call__即可作为装饰器?

为什么cached_property不需要__call__或__new__?

你搞混了两种不同类型的装饰器——cached_property不是用来装饰普通函数的可调用装饰器,而是专为类属性设计的描述符装饰器,它靠Python的描述符协议工作,根本不需要__call__或__new__。

具体来说:

  • 普通的装饰器类(比如用来包装函数的那种)需要__call__,是因为装饰后的结果得是个可调用对象,当你调用被装饰的函数时,实际触发的是装饰器实例的__call__方法。
  • 但cached_property的作用是把类里的方法转换成延迟加载的属性:当你用@cached_property装饰类中的方法后,这个方法会被替换成cached_property的实例,作为类的一个属性存在。当你访问实例的这个属性时(比如obj.my_prop),Python会自动触发描述符的__get__方法,而不是把它当作函数去调用。

看代码里的几个关键方法:

  • __init__:接收被装饰的方法,把它存起来,后续用来计算属性值。
  • __set_name__:获取这个属性在类中的名字(比如你装饰的方法叫my_prop,这里就拿到name='my_prop'),方便后续把计算结果缓存到实例的__dict__里,避免和描述符本身冲突。
  • __get__:核心逻辑在这里——当访问属性时,先检查实例有没有缓存好的值,没有的话就执行原来的方法计算结果,把结果存到实例的字典里,再返回结果;下次访问直接取缓存值,不用再计算。

简单说,cached_property的定位是属性描述符,不是可调用的装饰器,它的工作机制依赖Python的属性访问规则,自然不需要__call__或__new__来实现核心功能。

内容的提问来源于stack exchange,提问作者syheliel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:50:28