如何将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
相关产品推荐
相关产品推荐

