Python类内动态装饰器:如何在初始化时传递参数?
问题描述
我希望在类初始化时将wrapType参数传递给装饰器,使程序输出Argument passed to with_provider: WORKS,要求无需使用globals()实现,最好能通过self.wrapType=wrapType让self传递到with_provider装饰器中。我尝试了以下代码但未成功,因为类初始化时传递给装饰器的参数似乎是不可变的,同时希望装饰器能保留在类内以保证代码整洁。
尝试的代码
from functools import wraps WRAPTYPE = "DOES NOT WORK" class Test(): def __init__(self,wrapType): globals()["WRAPTYPE"] = wrapType def with_provider(wrapType): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): print("Argument passed to with_provider:", wrapType) return func(*args, **kwargs) return wrapper return decorator # Example usage @with_provider(WRAPTYPE) def example_function(self): print("Inside example_function") #%% t = Test("WORKS") t.example_function()
解决方案
可行。问题出在原代码的装饰器执行时机:@with_provider(WRAPTYPE)是在类定义阶段就执行的,此时传入的WRAPTYPE是初始值"DOES NOT WORK",后续实例化时修改全局变量无法改变已经绑定的参数。
要实现动态从实例获取wrapType,可以调整装饰器逻辑,让它在方法调用时从实例self中读取属性,而非在装饰阶段固定参数:
from functools import wraps class Test(): def __init__(self, wrapType): self.wrapType = wrapType # 将参数存入实例属性 @staticmethod def with_provider(func): @wraps(func) def wrapper(self, *args, **kwargs): # 调用时从实例self中动态获取wrapType print("Argument passed to with_provider:", self.wrapType) return func(self, *args, **kwargs) return wrapper @with_provider def example_function(self): print("Inside example_function") # 测试执行 t = Test("WORKS") t.example_function()
说明
- 装饰器
with_provider改为静态方法(避免类定义时需要实例),不再提前接收wrapType参数 - 装饰后的
wrapper函数会在调用时拿到实例self,直接访问self.wrapType,实现动态获取每个实例的参数 - 每个实例可以设置不同的
wrapType,互不干扰,也不需要依赖全局变量
内容的提问来源于stack exchange,提问作者Magdalini Klio
相关产品推荐
相关产品推荐

