如何使用Python类内部的实例方法装饰该类的其他成员方法
类内方法装饰实例方法的解决方案
问题根源
你代码报错的核心原因是:装饰器@foo的执行时机是类定义阶段,此时还没有任何Foobar类的实例被创建,被定义为实例方法的foo无法接收到实例self,只会把被装饰的bar函数作为第一个参数传入,自然就没有值传给func形参。
注意:你原代码中
print(self + " is doing something")的写法会报错,因为实例对象不能直接和字符串做拼接操作,需要先转为字符串,后续示例中使用f-string自动完成了类型转换。
可行方案
方案1:调整装饰器定义,在包装函数中获取实例
改动最小,完全满足你需要访问实例self的需求:
class Foobar: # 类定义阶段没有实例,装饰器不需要接收self参数 def foo(func): # 包装函数的第一个参数就是调用bar时传入的实例对象 def wrapped(self, *args, **kwargs): print(f"{self} is doing something") func(self, *args, **kwargs) return wrapped @foo def bar(self, *args, **kwargs): print("Foobar")
如果不希望foo被外部调用,可以将其重命名为私有命名_foo即可。
方案2:实例初始化阶段手动装饰
如果你必须保留foo作为实例方法的定义(比如需要单独调用foo完成其他装饰逻辑),可以把装饰操作移到__init__方法中,等实例创建完成后再执行装饰:
class Foobar: def __init__(self): # 实例创建完成后,用当前实例的foo方法装饰bar self.bar = self.foo(self.bar) def foo(self, func): def wrapped(*args, **kwargs): print(f"{self} is doing something") func(*args, **kwargs) return wrapped # 此处不需要加装饰器 def bar(self, *args, **kwargs): print("Foobar")
内容的提问来源于stack exchange,提问作者user16519472
相关产品推荐
相关产品推荐

