You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于闭包实现具有历史调用去重功能的装饰器bar?

用闭包实现记录历史调用的装饰器

没问题,用闭包来实现这个需求完全可行,不用全局变量也能轻松追踪函数的历史调用参数。我给你写个完整的实现,再拆解下逻辑:

def bar(func):
    # 用外层函数的变量保存上次调用的参数,初始为None(第一次调用无历史)
    last_args = None
    
    def wrapper(*args):
        nonlocal last_args
        # 对比当前参数和上次参数
        if args != last_args:
            # 参数不同,执行原函数(这里就是print)
            result = func(*args)
            # 更新历史参数为当前参数
            last_args = args
            return result
        else:
            # 参数相同,返回None不打印
            return None
    
    return wrapper

# 装饰printer函数
@bar
def printer(*args):
    print(*args)

测试效果:

printer("a")  # 输出: a
printer("a")  # 无输出,仅返回None
printer("a")  # 无输出,仅返回None
printer("b")  # 输出: b
printer("a")  # 输出: a

关键逻辑解释:

  • 闭包的作用:外层函数bar里的last_args变量会被内层的wrapper函数保留,每次调用printer其实都是调用wrapper,它能持续访问和更新last_args,完全不需要全局变量。
  • nonlocal关键字:如果不用nonlocal,内层函数里给last_args赋值会被当成局部变量,用它就能明确告诉Python我们要修改外层函数的last_args变量。
  • 参数对比:用args != last_args直接对比元组(因为*args会把传入的参数打包成元组),不管是单个参数还是多个参数都能正确对比。

这样就完美实现了你想要的功能——只有当本次调用参数和上次不同时才执行打印,相同则仅返回None。

内容的提问来源于stack exchange,提问作者bendaMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:27:53