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

discord.py机器人报UnboundLocalError:levelup变量赋值前被引用

问题复现代码

起始代码

with open('data/level','r') as file:
    to_level = file.readline()

client = commands.Bot(command_prefix=".")

触发报错的函数代码(第44行为if levelup == 81:)

@client.event
async def on_message(message):
 channel = client.get_channel(int(spam_id))
 if message.channel.id == int(spam_id):
   if message.author.id == poketwo:
     if message.embeds:
       embed_content = message.embeds[0].description
       if 'now level' in embed_content:
                    split = embed_content.split(' ')
                    a = embed_content.count(' ')
                    levelup = int(split[a].replace('!', ''))
 if levelup == 81:
   spam.cancel()
   await channel.send(f".s {to_level}")
   spam.start()
   with open('data/level', 'r') as fi:
                            
data = fi.read().splitlines(True)
   with open('data/level', 'w') as fo: 
     fo.writelines(data[1:])
 await client.process_commands(message)

抛出的错误信息

Ignoring exception in on_message 
Traceback (most recent call last): 

File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 301, in _run_event 
await coro(*args, **kwargs) 
File "main.py", line 44, in on_message

if levelup == 81: 
UnboundLocalError: local variable 'levelup' referenced before assignment

错误产生原因
  • Python函数内的局部变量必须先完成赋值才能被访问。levelup的赋值逻辑被嵌套在4层if判断内部,只有所有判断条件全部命中(消息来自指定spam频道、发送者是poketwo账号、消息携带embed、embed描述包含now level字段)时,才会给levelup赋值。只要任意一个条件不满足,levelup变量就不会被创建,后续代码直接读取该变量就会触发「赋值前引用局部变量」的错误。
  • 代码还存在缩进错误:读取文件内容的data = fi.read().splitlines(True)没有缩进在with open('data/level', 'r') as fi:的代码块范围内,就算前面的等级判断正常执行,到文件操作步骤也会抛出IO相关错误。

修复方法
  • 在on_message函数的开头位置给levelup设置默认初始值,比如levelup = 0,保证不管走哪个分支逻辑,这个变量都已经被定义,不会出现未创建就访问的问题。
  • 修正文件读取部分的缩进错误,把data = fi.read().splitlines(True)缩进到对应的with代码块内,保证文件句柄处于打开状态时执行读取操作。
  • 可选优化:把if levelup == 81的判断逻辑挪到外层频道判断的内部,非指定频道的消息不需要走等级判断逻辑,减少无意义的性能消耗。

修复后的完整代码

with open('data/level','r') as file:
    to_level = file.readline()

client = commands.Bot(command_prefix=".")

@client.event
async def on_message(message):
    levelup = 0  # 初始化变量解决未赋值引用问题
    channel = client.get_channel(int(spam_id))
    if message.channel.id == int(spam_id):
        if message.author.id == poketwo:
            if message.embeds:
                embed_content = message.embeds[0].description
                if 'now level' in embed_content:
                    split = embed_content.split(' ')
                    a = embed_content.count(' ')
                    levelup = int(split[a].replace('!', ''))
        # 等级判断移入频道判断分支,减少无效判断
        if levelup == 81:
            spam.cancel()
            await channel.send(f".s {to_level}")
            spam.start()
            with open('data/level', 'r') as fi:
                # 修正缩进,在with块内读取文件
                data = fi.read().splitlines(True)
            with open('data/level', 'w') as fo: 
                fo.writelines(data[1:])
    await client.process_commands(message)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 22:57:21