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

开发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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:54:26