开发Discord Bot时函数内赋值变量外部调用报NameError问题求助
问题解决:NameError: name 'row2' is not defined
核心问题
row2和row4是userIdThing函数内部的局部变量,函数外部无法直接访问。而且你调用该函数时没有接收它返回的结果,导致后续代码找不到这两个变量。此外还有几个隐藏问题会影响功能正常运行,一起给你修复。
分步修复
1. 接收函数返回值
在on_message事件里调用userIdThing时,必须接收它返回的两个值,不然外面根本拿不到数据:
row2, row4 = userIdThing(str(message.author.id))
注意:CSV里的User ID是字符串类型,你之前传int(message.author.id)会和字符串ID不匹配,要转成字符串再传入。
2. 跳过CSV表头
你的CSV第一行是表头,循环读取时会把表头也当成数据行处理,导致ID匹配失败,必须跳过第一行:
def userIdThing(user_id): print("ID THING") with open('data.csv', 'r') as dataFile: print("CSV OPEN") dataFileReader = csv.reader(dataFile) next(dataFileReader) # 跳过表头行 for row in dataFileReader: if row[0] == user_id: row2 = int(row[1]) row4 = int(row[4]) print(row2, " ", row4) return row2, row4 # 没找到匹配ID时返回默认值,避免报错 return 0, 0
3. 修复图表保存问题
你直接发送test.png但没把Matplotlib生成的图表保存到文件,必须先执行保存操作:
plt.plot([0, row2, row4]) plt.ylabel('Follower Increase') plt.xlabel("days") plt.savefig("test.png") # 新增:把图表保存到文件 plt.close() # 关闭图表释放资源 await message.channel.send(file=discord.File("test.png"))
4. 替换阻塞式sleep为异步sleep
在Discord Bot的异步事件里用time.sleep会卡住整个Bot,换成异步的asyncio.sleep:
import asyncio # ... 其他代码 ... await asyncio.sleep(3)
5. 移除无效的手动文件关闭
with open(...)语句会自动帮你关闭文件,不需要手动写dataFile.close(而且你之前写的dataFile.close少了括号,根本没执行)。
完整修复后的代码片段
import os import csv import discord import matplotlib.pyplot as plt import asyncio def fileDeleteion(fileName): if os.path.exists(fileName): os.remove(fileName) else: print("The file does not exist") def userIdThing(user_id): print("ID THING") with open('data.csv', 'r') as dataFile: print("CSV OPEN") dataFileReader = csv.reader(dataFile) next(dataFileReader) # 跳过表头 for row in dataFileReader: if row[0] == user_id: row2 = int(row[1]) row4 = int(row[4]) print(row2, " ", row4) return row2, row4 # 未找到匹配ID时返回默认值 return 0, 0 @client.event async def on_message(message): if message.content == "!graph": fileDeleteion("test.png") fileDeleteion("id.csv") # 接收函数返回的结果 row2, row4 = userIdThing(str(message.author.id)) await asyncio.sleep(3) # 生成图表并保存 plt.plot([0, row2, row4]) plt.ylabel('Follower Increase') plt.xlabel("days") plt.savefig("test.png") plt.close() await message.channel.send(file=discord.File("test.png")) fileDeleteion("test.png") fileDeleteion("id.csv")
额外提醒
- 确保你的Bot在服务器里有发送文件的权限
- 如果用户ID不在CSV里,当前代码会用0、0生成图表,你可以加个判断,比如返回0时发送消息告知用户未找到数据
内容的提问来源于stack exchange,提问作者Mallard
相关产品推荐
相关产品推荐

