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

Python中为已用@property装饰的方法再套装饰器为何失效?

问题原因分析

你遇到的问题核心是装饰器的应用顺序错误,导致@property的特性被覆盖了。

Python中装饰器的执行顺序是从下往上的,也就是离被装饰函数最近的装饰器先生效。你的代码里:

@my_decorator
@property
def x(self):
    return 42

实际执行逻辑是:先把x方法转成property实例,再用my_decorator去装饰这个property对象。但my_decorator返回的是一个普通的wrapper函数,而非property实例。当你访问obj.x时,Python不会触发property的getter逻辑,而是直接返回这个绑定到实例的wrapper方法,这就是你看到输出是<bound method...>的原因。

解决方案

把装饰器的顺序颠倒过来,让@property作为最外层装饰器,先应用自定义装饰器到原方法,再把包装后的方法转为property:

# Define a decorator
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Decorator applied")
        return func(*args, **kwargs)
    return wrapper

# Apply the decorator over the method
class MyClass:
    @property
    @my_decorator
    def x(self):
        return 42

# Test the decorated method
obj = MyClass()
print(obj.x)  # 输出:Decorator applied 然后是42

此时的执行逻辑是:先用my_decorator包装原x方法,得到带打印逻辑的wrapper,再用@property把这个wrapper设置为属性的getter。当访问obj.x时,会触发property的get操作,调用wrapper,进而执行原方法并输出预期结果。

多装饰器场景的注意事项

如果实际场景有多个自定义装饰器,所有功能型装饰器(比如日志、缓存类的装饰器)都要放在@property的下方(也就是更靠近原方法),最后用@property作为最外层装饰器,确保最终生成的是property实例而非普通函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:12:33