使用discord.py开发机器人时get_member()返回NoneType问题求助
Discord机器人
get_member返回NoneType问题修复方案 核心触发原因
get_member返回None基本都是以下三类问题导致的,按出现概率从高到低排序:
- 传入的用户ID类型错误:你从文本文件读取的用户ID是字符串格式,而
get_member要求传入int类型的ID,类型不匹配自然查不到结果 - 未开启成员访问权限:Discord API v10及discord.py v2.0之后,服务器成员数据属于敏感权限,默认不开放,需要手动开启权限
- 目标用户已退出当前服务器,无匹配数据
分步修复操作
- 第一步:开启机器人成员访问权限
- 打开Discord开发者后台,进入你当前机器人的管理页,切换到「Bot」选项卡
- 找到「Privileged Gateway Intents」分组,打开「Server Members Intent」开关后保存设置
- 代码中初始化客户端时声明对应权限,示例代码如下:
import discord # 声明成员访问意图 intents = discord.Intents.default() intents.members = True # 初始化client时传入意图参数 client = discord.Client(intents=intents) # 如果你用的是commands.Bot,写法如下: # from discord.ext import commands # bot = commands.Bot(command_prefix='你的指令前缀', intents=intents)
- 第二步:修正
get_user_details方法的类型转换和空值判断
def get_user_details(user_id): # 先把读取到的字符串ID转成int,同时去除前后空白字符避免脏数据 user_id = int(user_id.strip()) _server = client.get_guild(829439043753607228) _user = _server.get_member(user_id) # 增加空值判断,避免后续访问属性时报错 if not _user: return None, f"未知用户(ID:{user_id})" _username = f"{_user.name}#{_user.discriminator}" return _user, _username
- 第三步:修复你代码中遗留的日志写入逻辑错误
你当前写入jester_log时错误判断了user_log是否为空,会导致日志文件开头多一个逗号,修正如下:
with open(jester_log, 'a') as file: # 原来的错误判断是if not is_file_empty(user_log): # 改为判断jester_log本身是否为空 if not is_file_empty(jester_log): file.write(",") file.write(str(new_jester_id)) print(f'User "{new_jester_username}" logged to the jester file')
兜底方案
如果因为本地缓存未同步导致get_member还是查不到数据,可以改用异步的fetch_member方法主动调用Discord API拉取最新用户数据,注意该方法是协程需要await调用,对应方法也要改为异步:
async def get_user_details(user_id): user_id = int(user_id.strip()) _server = client.get_guild(829439043753607228) try: # 主动从服务器拉取用户数据,不走本地缓存 _user = await _server.fetch_member(user_id) except discord.NotFound: return None, f"未知用户(ID:{user_id})" _username = f"{_user.name}#{_user.discriminator}" return _user, _username
内容的提问来源于stack exchange,提问作者Luke Walker
相关产品推荐
相关产品推荐

