Pycord使用wait_for时出现AttributeError问题求助
问题分析与解决方案
错误原因拆解
第一个错误根源
你使用Slash命令时,回调函数的ctx是ApplicationContext类型,它没有message属性(Slash命令并非通过用户消息触发),所以ctx.message的值为None,访问ctx.message.content自然会抛出'NoneType' object has no attribute 'content'错误。
第二个错误根源
调用bot.wait_for时,你错误地写成了check=check(message)——这里的message实际是Slash命令的ctx(ApplicationContext对象),你直接执行了check函数并把结果传给wait_for,而非传入函数本身。wait_for('message')需要的是一个接收Message对象的函数,而你传入的是布尔值,且执行时把ApplicationContext传给check,它没有content属性,因此触发新的报错。
修正后的完整代码
import asyncio import sqlite3 # 假设你已经初始化了bot和数据库连接c @bot.slash_command(name="buy") async def buy(ctx): # 提前查询价格,避免在check中重复访问数据库 target_type = "你的目标类型" # 替换为实际的type值 c.execute("SELECT price FROM accounts WHERE type=?", (target_type,)) price_result = c.fetchone() if not price_result: await ctx.respond("未找到对应类型的价格") return expected_price = str(price_result[0]) # 转为字符串,匹配消息内容格式 # 定义check函数,参数为wait_for自动传入的Message对象 def check(message): # 1. 验证消息作者是否为目标用户 if message.author.id != 282859044593598464: return False # 2. 验证消息开头格式 expected_start = f"**:moneybag: | {message.author.display_name}, has transferred " if not message.content.startswith(expected_start): return False # 3. 验证是否提及目标账号 if "<@969279390447984660>" not in message.content: return False # 4. 验证价格是否在消息中 if expected_price not in message.content: return False return True try: # 关键:传入函数引用check,而非调用check() matched_message = await bot.wait_for('message', check=check, timeout=60) await ctx.respond(f"已捕获符合条件的转账消息:{matched_message.content}") except asyncio.TimeoutError: await ctx.respond("等待超时,未收到有效转账消息")
关键修正点
- 提前查询数据库:将价格查询移到
check函数外,避免每次检查消息都重复访问数据库,同时拿到预期价格的字符串格式。 - 正确定义check函数:
check的参数是Message对象(由wait_for('message')自动传入),直接使用message.content、message.author等属性。 - 修正wait_for调用方式:传入
check=check(函数本身),而非check(message)(函数执行结果)。 - 添加超时处理:避免命令因未收到消息而一直挂起。
额外注意事项
- 确保你的Bot已开启
MessageContent权限(Discord开发者门户中设置),否则无法读取用户消息内容。 - 使用
fetchone()替代fetchall():因为你只查询单条价格,fetchone()返回单个元组,更易处理。
内容的提问来源于stack exchange,提问作者signalmute
相关产品推荐
相关产品推荐

