Python如何实现可重复调用上次执行函数的repeat()方法?
实现方案
方案1:装饰器记录调用状态(推荐)
思路是给目标函数添加装饰器,每次调用时自动记录最近执行的函数对象和传入的参数,repeat()函数直接读取记录执行即可,支持保留上次调用的入参:
# 全局状态,记录最后一次调用的函数和参数 _last_called = { "func": None, "args": (), "kwargs": {} } def record_call(func): def wrapper(*args, **kwargs): # 调用前先记录本次调用的信息 _last_called["func"] = func _last_called["args"] = args _last_called["kwargs"] = kwargs return func(*args, **kwargs) return wrapper # 给原有函数添加装饰器 @record_call def a(name = None): return "Hello " + name @record_call def b(say = "something"): return "I will say " + say def repeat(): if not _last_called["func"]: raise RuntimeError("没有调用过任何函数,无法重复执行") return _last_called["func"](*_last_called["args"], **_last_called["kwargs"])
使用示例:
print(a("小明")) # 输出 Hello 小明 print(repeat()) # 输出 Hello 小明 print(b("早上好")) # 输出 I will say 早上好 print(repeat()) # 输出 I will say 早上好
该方案支持完整保留上次调用的位置参数、关键字参数,不需要修改原有函数的逻辑代码
方案2:无侵入猴子补丁方案
如果不想修改原有函数的装饰器声明,可以用运行时打补丁的方式实现,完全不改动原有a、b函数的定义:
_last_called = { "func": None, "args": (), "kwargs": {} } # 原有函数保持不变 def a(name = None): return "Hello " + name def b(say = "something"): return "I will say " + say # 批量给目标函数打补丁 def patch_functions(func_list): def wrapper_generator(func): def wrapper(*args, **kwargs): _last_called["func"] = func _last_called["args"] = args _last_called["kwargs"] = kwargs return func(*args, **kwargs) return wrapper for func in func_list: globals()[func.__name__] = wrapper_generator(func) # 初始化补丁,只需执行一次 patch_functions([a, b]) def repeat(): if not _last_called["func"]: raise RuntimeError("没有调用过任何函数,无法重复执行") return _last_called["func"](*_last_called["args"], **_last_called["kwargs"])
该方案的使用效果和方案1完全一致,适合不能修改原有函数定义的场景。
内容的提问来源于stack exchange,提问作者Talos0248
相关产品推荐
相关产品推荐

