Discord机器人实现服务器专属绑定频道时出现AttributeError如何解决
报错根本原因
AttributeError: 'NoneType' object has no attribute 'send' 是因为 discord.utils.get 没有匹配到符合条件的频道,返回了None,你对空值调用send方法就触发了报错,导致get查询失败的具体原因有三个:
- 你没有执行
get_channel函数就直接把函数对象传给了name参数,相当于查询名称等于函数本身的频道,自然不可能找到 - 你定义的
get_channel入参是client和message,但on_member_join事件里只有member对象,就算你尝试调用函数也会因为参数不匹配报错 - 新加入的服务器默认配置的频道名是空字符串,如果管理员没有执行
cc命令设置有效频道名,也会查询失败
修复方案
1. 调整工具函数定义
修改get_channel函数,简化入参适配所有场景,函数名调整为更语义化的get_channel_name避免歧义:
def get_channel_name(guild_id): with open('channels.json', 'r') as f: channels = json.load(f) return channels.get(str(guild_id), '')
2. 重写on_member_join事件逻辑
先调用工具函数拿到配置的频道名,增加多层非空判断避免极端场景报错:
@client.event async def on_member_join(member): channel_name = get_channel_name(member.guild.id) # 未配置频道直接跳过 if not channel_name: return channel = discord.utils.get(member.guild.channels, name=channel_name) # 频道存在才发送消息 if channel: await channel.send(f'Welcome {member.mention}')
3. 可选优化cc命令
将原来的参数名prefix改为channel_name避免和命令前缀混淆,同时增加频道有效性校验,避免存储无效的频道名:
@client.command() async def cc(ctx, channel_name): # 校验频道是否真实存在 exist_channel = discord.utils.get(ctx.guild.channels, name=channel_name) if not exist_channel: await ctx.send("错误:当前服务器不存在该名称的频道") return with open('channels.json', 'r') as f: channels = json.load(f) channels[str(ctx.guild.id)] = channel_name with open('channels.json', 'w') as f: json.dump(channels,f) await ctx.send('done')
内容的提问来源于stack exchange,提问作者Hondaman727
相关产品推荐
相关产品推荐

