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

Discord机器人嵌套函数调用异常:倒计时输出无法正常触发

修复Discord机器人倒计时装饰器的嵌套调用问题

原代码核心问题分析

  1. 装饰器返回逻辑错误:原代码return wrapper("*args, **kwargs")直接调用了wrapper并返回结果,而非返回wrapper函数本身。这导致装饰器在定义阶段就执行了一次,被装饰的countfunc最终变成了wrapper的返回值(即None)。
  2. 计数器每次被重置:wrapper内部每次调用都重新设置wrapper.counter = 3,导致计数器永远只会从3减到2,无法实现从3到0的递减逻辑。
  3. 被装饰函数参数冗余:@count def countfunc(wrapper):不需要接收wrapper参数,装饰器包装后的函数调用时不会传入该参数。
  4. 外部调用方式错误:print(countfunc)是打印函数对象(此时已为None),而非调用触发逻辑的countfunc()。

修复后的代码

def count(countfunc):
    # 将计数器初始化移到wrapper外部,确保仅在装饰器应用时初始化一次
    wrapper.counter = 3
    wrapper.start = 3

    def wrapper(*args, **kwargs):
        # 可选:限制计数器到0后不再继续递减
        if wrapper.counter <= 0:
            print("Already banned, no more warnings to issue")
            return countfunc(*args, **kwargs)
        
        wrapper.counter -= 1
        if wrapper.counter == 0:
            print(f"has ran out of warnings & is now banned on the server for 1 day")
        else:
            print(f"has {wrapper.counter} warnings left")
        return countfunc(*args, **kwargs)
    
    # 返回wrapper函数本身,而非调用结果
    return wrapper

# 被装饰函数无需额外参数
@count
def countfunc():
    return

# 调用函数触发倒计时逻辑
countfunc()
countfunc()
countfunc()
countfunc()

修复说明

  1. 修正装饰器返回值:将return wrapper("*args, **kwargs")改为return wrapper,让装饰器正确为countfunc包装逻辑,而非立即执行并返回None。
  2. 调整计数器初始化位置:把wrapper.counter = 3移到wrapper函数外部,确保计数器仅初始化一次,每次调用countfunc()时持续递减。
  3. 移除冗余参数:删除countfunc的wrapper参数,匹配装饰器的调用逻辑。
  4. 正确触发函数逻辑:使用countfunc()调用函数,而非打印函数对象,触发wrapper内的倒计时输出。

输出结果

has 2 warnings left
has 1 warnings left
has ran out of warnings & is now banned on the server for 1 day
Already banned, no more warnings to issue

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:00:53