如何编写可修改已有函数的包装函数以调整参数?
如何编写可修改已有函数的包装函数以调整参数?
其实你现在的调用思路有个小误区哦——你写的offset_b(add(1, 2), 0.5)是先执行了add(1,2)得到结果3,再把这个结果传给offset_b,这时候早就没法修改原函数的参数了。我们需要换个思路:先包装函数本身,再调用包装后的函数传入参数。
这里用包装函数(也就是你说的wrapper)就能完美解决,具体实现如下:
def add(a, b): return a + b def minus(a, b): return a - b def offset_b(func, n): # 定义一个包装函数,接收原函数需要的参数 def wrapper(a, b): # 把第二个参数b减去n,再传递给原函数执行 return func(a, b - n) # 返回包装后的新函数 return wrapper
使用方式:
- 先包装原函数,得到一个自动处理参数的新函数:
# 包装add,得到会自动把b减0.5的新add函数 offset_add = offset_b(add, 0.5) # 调用新函数,实际执行 add(1, 2 - 0.5) print(offset_add(1, 2)) # 输出 2.5 # 同理处理minus offset_minus = offset_b(minus, 0.5) print(offset_minus(1, 2)) # 输出 -0.5
- 如果只是临时用一次,也可以直接链式调用,不用提前存新函数:
print(offset_b(add, 0.5)(1, 2)) # 直接执行包装后的函数,输出2.5
扩展:更通用的包装函数
如果以后你的函数参数数量或位置有变化,可以用*args和**kwargs来让包装函数更灵活。比如假设你想调整任意位置的参数,只需要修改wrapper里的逻辑:
def offset_param(func, param_index, n): def wrapper(*args, **kwargs): # 把指定位置的参数减去n args_list = list(args) args_list[param_index] -= n return func(*args_list, **kwargs) return wrapper # 比如调整第二个参数(索引是1)减0.5,用法和之前一样 offset_add = offset_param(add, 1, 0.5) print(offset_add(1, 2)) # 还是2.5
这样不管原函数有多少参数,只要指定要调整的参数位置,就能实现批量修改啦~
备注:内容来源于stack exchange,提问作者herohaha
相关产品推荐
相关产品推荐

