如何从被装饰函数调用时动态传递参数至装饰器
解决方案:动态修改装饰器的重试次数
没问题,这个需求很常见,只需要对你的装饰器内层包装函数做一点小调整,就能实现调用时动态覆盖max_repeating参数的效果。
核心思路
装饰器的内层wrap_function是实际被调用的入口,我们可以在这里优先读取调用时传入的max_repeating参数(如果有的话),没有的话再使用装饰时设置的默认值。这样既保留了装饰时的配置,又支持调用时的动态修改。
修改后的完整代码
def decorator_wraper(max_repeating=20): def decorator(function): def wrap_function(*args, **kwargs): # 优先使用调用时传入的max_repeating,否则用装饰器的默认值 # 用pop是为了避免把这个参数传递给原函数(如果原函数不需要的话) # 如果原函数本身需要max_repeating参数,把pop改成get即可 current_max = kwargs.pop('max_repeating', max_repeating) print(f"当前重试次数上限: {current_max}") repeat = 0 while repeat < current_max: try: # 调用原函数,传递剩余的参数 return function(*args, **kwargs) except Exception: print(f"第{repeat+1}次执行失败,重试中...") pass repeat += 1 print(f"已达到最大重试次数{current_max},执行失败") return wrap_function return decorator # 测试用的被装饰函数 @decorator_wraper(5) def decorate_me_with_argument(max_repeating=10): print(f"函数内部的max_repeating参数值: {max_repeating}") @decorator_wraper() def decorate_me_with_default(): print("decorate_me_with_default 执行成功")
调用测试
# 装饰时的配置生效 decorate_me_with_argument() # 输出: # 当前重试次数上限: 5 # 函数内部的max_repeating参数值: 10 decorate_me_with_default() # 输出: # 当前重试次数上限: 20 # decorate_me_with_default 执行成功 # 调用时动态修改重试次数 decorate_me_with_argument(max_repeating=3) # 输出: # 当前重试次数上限: 3 # 函数内部的max_repeating参数值: 3 decorate_me_with_default(max_repeating=8) # 输出: # 当前重试次数上限: 8 # decorate_me_with_default 执行成功
细节说明
- 如果你的被装饰函数不需要
max_repeating作为自身参数,用kwargs.pop()可以把这个参数从传递给原函数的参数中移除,避免出现“参数过多”的错误。 - 如果你的被装饰函数需要
max_repeating参数(比如例子中的decorate_me_with_argument),把pop改成get即可,这样原函数也能拿到这个参数值:current_max = kwargs.get('max_repeating', max_repeating) - 建议用关键字参数传递
max_repeating(比如func(max_repeating=3)),这样可以避免和原函数的位置参数冲突,代码可读性也更好。
内容的提问来源于stack exchange,提问作者tomm
相关产品推荐
相关产品推荐

