类方法使用带参Python装饰器无法传入类属性参数求助
解决类方法中无法使用实例属性作为装饰器参数的问题
你的条件装饰器在独立函数上运行正常,但在类方法中使用时,直接传入self.verbose会触发NameError,核心原因是装饰器在类定义阶段就会执行,此时类还没有被实例化,self这个实例对象根本不存在,自然无法访问它的属性。
下面是几种可行的解决方法:
方法一:让装饰器在运行时读取实例属性
修改装饰器,不再提前接收flag参数,而是在调用方法时从实例(也就是方法的第一个参数self)中直接读取verbose属性:
class MyDec(object): def __call__(self, original_func): def wrapper(self, *args, **kwargs): if self.verbose: print('in decorator action') original_func(self, *args, **kwargs) return wrapper class One: def __init__(self, verbose): self.verbose = verbose @MyDec() def print_something(self): print('in decorated func action') # 测试 one = One(False) one.print_something() # 输出:in decorated func action one2 = One(True) one2.print_something() # 输出: # in decorator action # in decorated func action
方法二:让装饰器接收属性名作为参数
如果需要装饰器适配不同的属性名,可以让它接收属性名称字符串,运行时通过getattr从实例中获取对应值:
class MyDec(object): def __init__(self, attr_name): self.attr_name = attr_name def __call__(self, original_func): def wrapper(self, *args, **kwargs): if getattr(self, self.attr_name): print('in decorator action') original_func(self, *args, **kwargs) return wrapper class One: def __init__(self, verbose): self.verbose = verbose @MyDec('verbose') def print_something(self): print('in decorated func action') # 测试 one = One(False) one.print_something() # 输出:in decorated func action one2 = One(True) one2.print_something() # 输出: # in decorator action # in decorated func action
方法三:使用函数式装饰器(更简洁)
如果不需要类形式的装饰器,用函数式写法会更轻便:
def my_dec(attr_name): def decorator(original_func): def wrapper(self, *args, **kwargs): if getattr(self, attr_name): print('in decorator action') return original_func(self, *args, **kwargs) return wrapper return decorator class One: def __init__(self, verbose): self.verbose = verbose @my_dec('verbose') def print_something(self): print('in decorated func action')
这几种方法的核心思路都是延迟属性的读取时机,从类定义阶段推迟到方法实际调用的阶段,此时实例已经存在,就能正常访问实例属性了。
内容的提问来源于stack exchange,提问作者Danil
相关产品推荐
相关产品推荐

