Discord tasks.loop任务调用channel.send报NoneType无send属性错误求助
问题原因与解决方案
报错根因
AttributeError: 'NoneType' object has no attribute 'send' 报错的直接原因是 client.get_channel(908484216084385853) 执行后返回了None,没有获取到对应的频道对象,自然无法调用send方法。
为什么指令中运行正常、定时任务中报错
@client.command()装饰的指令只会在Bot完成登录、Discord服务器/频道等资源的内部缓存全部加载完毕后才会响应触发,此时调用get_channel可以正常读取缓存拿到对应频道对象。- 绝大多数出现该问题的场景是:定时任务
tasks.loop在Bot启动流程中被过早触发,第一次循环执行时Bot还未完成登录、缓存还未初始化,因此get_channel找不到对应频道返回None。
修复方案
方案1:给定时任务加前置等待钩子
通过before_loop装饰器给定时任务添加前置逻辑,等待Bot完全就绪后再执行循环内容,同时可以加非空判断做兜底兼容:
@tasks.loop(seconds = 40) async def t(): channel = client.get_channel(908484216084385853) # 非空判断兜底,避免频道删除、Bot被踢等极端场景报错 if not channel: return if len(error_list) == len(names): await channel.send('Nobody is online!') else: for i in range(len(friends_list)): await channel.send(friends_list[i].capitalize()) # 新增前置钩子,等待Bot就绪 @t.before_loop async def before_t(): await client.wait_until_ready()
方案2:在on_ready事件中启动定时任务
直接把定时任务的启动逻辑放到Bot就绪的事件回调中,保证启动时缓存已经加载完成:
@client.event async def on_ready(): print(f'登录成功:{client.user}') # 此处启动定时任务 t.start()
内容的提问来源于stack exchange,提问作者오서준
相关产品推荐
相关产品推荐

