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

Pycord发送带本地缩略图的Embed到指定频道报IO关闭文件错误

问题根因

抛出ValueError: I/O operation on closed file的核心原因是你复用了已经被关闭IO流的discord.File实例。
Pycord在完成文件上传发送后,会自动关闭discord.File绑定的底层文件指针。你现在把localThumbnail实例定义在回调外层,只要这个实例之前被用于过其他发送场景(比如交互触发时先在当前频道发了消息、或者私信场景已经用过一次这个File对象),后续再拿这个已经关闭流的实例跨频道发送,就会触发读文件失败的错误。这也是为什么同一份逻辑在当前频道、私信场景能用,跨频道发就报错——前者是第一次使用File实例,流是正常打开状态,后者是复用已经被关闭的实例。
另外你的代码里混入了interactions库的导入语句,interactions.py是和Pycord独立的另一套Discord机器人开发框架,混导容易引发类不兼容的隐性问题,建议删除。

排查方向
  • 检查localThumbnail的定义位置:如果是在按钮交互回调的外层全局定义,且在跨频道发送前已经被其他发送逻辑调用过,就会出现流被提前关闭的问题。
  • 校验附件引用匹配性:attachment://协议后的文件名必须和传入send方法的discord.File的文件名完全一致,当前代码的命名匹配是正确的,这部分不需要调整。
  • 排查手动关闭流的逻辑:确认代码中没有手动调用localThumbnail.close()的操作,同时确认本地图片路径在程序运行时的访问权限正常,不存在文件打开失败的情况。
修复方案

不要提前实例化全局复用的discord.File对象,只把固定的文件路径、附件引用URI抽为常量,每次执行发送操作前重新实例化新的discord.File对象即可,新实例会重新打开本地文件流,不会出现流关闭的问题。
修正后的核心代码:

import discord
from discord.ui import Select, View, Button
from discord.utils import get

# 仅抽固定配置为常量,不要提前实例化discord.File
THUMBNAIL_PATH = "./Source/Images/thumbnail-placeholder.png"
THUMBNAIL_ATTACH_REF = "attachment://thumbnail-placeholder.png"

# 发送逻辑内每次新建File实例
embedConfirm.set_thumbnail(url=THUMBNAIL_ATTACH_REF)
local_thumbnail = discord.File(THUMBNAIL_PATH)
target_channel = bot.get_channel(int(ADMINREPORTCHANNEL))
await target_channel.send(embed=embedConfirm, view=view, file=local_thumbnail)

注意:如果需要同时向当前交互频道、目标管理频道发送同一份带缩略图的消息,必须为两次send操作分别实例化独立的discord.File对象,绝对不能复用同一个实例,每次send完成后Pycord都会自动关闭对应文件的IO流,复用必然触发本次的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:45:41