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

Python开发Telegram Bot时嵌套函数调用报UnboundLocalError

问题原因

这个报错和普通变量触发的UnboundLocalError遵循完全一致的Python作用域规则,不存在函数特殊的情况:

  1. Python在解析函数体时,会将所有在函数内被赋值/定义的名称标记为当前函数作用域的局部变量,不会向外层作用域查找
  2. 函数定义本质是给名称赋值的操作,你写的def printmsg(text): ...等价于给当前作用域的printmsg变量绑定一个函数对象
  3. 你的代码里所有对printmsg的调用都写在了printmsg定义语句的前面,代码从上到下执行到调用行时,局部变量printmsg还没有被赋值,就触发了“引用前未赋值”的错误。

另外你的代码还存在一个隐藏的前置报错点:reply函数的入参写了adopo_list=adopo_list,但全局作用域并没有定义adopo_list,你全局定义的回复告别消息的列表叫goodbye_list,就算修了printmsg的位置问题,这里也会触发NameError。

修复方法
  • 最小改动方案:把printmsg的嵌套函数定义移动到reply函数内所有调用逻辑的最前面,同时修正入参里adopo_list绑定的全局变量名。修正后的核心代码如下:
# This function has to choose the appropriate way to reply to the user, based on what he/she wrote
def reply(update, context, ciao_counter=0, ciao_list=ciao_list, greatings_list=greatings_list, adopo_list=goodbye_list, eh_list=eh_list):
    # 先定义printmsg,再执行后续调用逻辑
    def printmsg(text):
        update.message.reply_text(text)

    msg = update.message.text.lower()
    match msg:
        case msg if msg in greatings_list: 
            match ciao_counter:
                case 0: 
                    printmsg(choice(ciao_list))
                    ciao_counter += 1
                case 1:
                    printmsg('Mi hai già salutato, non serve che lo fai di nuovo')
                    ciao_counter += 1
                case 2:
                    printmsg('Mi. hai. gia. salutato.')
                    ciao_counter += 1
                case 3:
                    printmsg('Basta, non ti rispondo più')
                    ciao_counter += 1
                case _:
                    printmsg('...')
        
        case msg if 'a dopo' in msg:
            printmsg(choice(adopo_list))
            ciao_counter = 0

        case _:
            printmsg(choice(eh_list))
  • 可选优化方案:如果后续多个处理函数都要用到快捷发消息的逻辑,可以把printmsg提到全局作用域定义,不需要每个处理函数里都嵌套定义,减少重复代码。

附加提示:你当前把ciao_counter设为函数默认参数的写法存在逻辑隐患,Python函数的默认参数在函数定义时就会被初始化,所有调用reply的请求会共享同一个计数器变量,不会按你预期的每个用户单独计数。如果要做用户维度的计数,需要把计数存在context.user_data这类独立的存储里,这个不属于本次报错的范畴,按需调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:51:19