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

如何将self传入Python装饰器?类方法装饰适配方案咨询

解决类装饰器访问实例属性的问题

你的问题核心是:用类装饰器Cage装饰实例方法时,装饰器需要获取实例(self),但直接用@Cage语法糖时,装饰器初始化阶段还没有实例,导致缺少parent参数报错。下面给两种实用的解决办法:

方案一:调整装饰器类的结构,在调用时接收实例

直接修改Cage类,让它的__init__只接收被装饰的方法,然后在__call__方法中接收实例(也就是原方法的self),这样调用方法时就能拿到实例属性了:

class Cage:
    def __init__(self, func):
        self.func = func

    def __call__(self, parent, *args, **kwargs):
        # parent就是Dog的实例self,直接访问属性
        print(f"访问Dog实例属性:{parent.name}")
        # 调用原方法时要把parent传进去
        return self.func(parent, *args, **kwargs)

class Dog:
    def __init__(self, name):
        self.name = name

    @Cage  # 现在可以正常用语法糖了
    def dosugar(self):
        print("汪汪汪")

poppy = Dog("Poppy")
poppy.dosugar()

方案二:用函数装饰器包裹类装饰器(不修改原Cage)

如果不想改动已写好的Cage类,可以加一层函数装饰器作为中间层,在调用方法时动态传入实例:

class Cage:
    def __init__(self, func, parent):
        self.func = func
        self.parent = parent

    def __call__(self):
        print(f"访问Dog实例属性:{self.parent.name}")
        self.func()

# 新增的函数装饰器,负责传递实例
def cage_decorator(func):
    def wrapper(parent, *args, **kwargs):
        # 每次调用方法时,创建Cage实例并传入当前实例parent
        return Cage(func, parent)()
    return wrapper

class Dog:
    def __init__(self, name):
        self.name = name

    @cage_decorator  # 用这个包裹后的装饰器
    def dosugar(self):
        print("汪汪汪")

poppy = Dog("Poppy")
poppy.dosugar()

这两种方法都能让你用@语法糖简化写法,同时让Cage访问到Dog实例的属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:02:44