Discord.py Cogs中client.wait_for报错:非异步上下文无法访问loop属性
Discord.py Cog中使用wait_for报错"loop attribute cannot be accessed in non-async contexts"
问题根源
你遇到的错误核心有两个原因:
- Cog中错误使用全局
client变量调用wait_for:Cog作为机器人的扩展模块,必须通过类实例的self.bot属性访问机器人对象,全局client在Cog上下文里无法正确关联事件循环。 - 代码存在拼写错误:
client.await_for是错误写法,正确方法名为wait_for。
解决方案步骤
- 确保Cog类正确继承
commands.Cog,并在初始化方法中接收bot参数绑定到self.bot - 将所有
client.wait_for及错误的client.await_for替换为self.bot.wait_for - 提取重复代码逻辑(如消息检查、猜数字循环),减少冗余并提升可维护性
修正后的完整代码
import re import random from discord.ext import commands class GuessCog(commands.Cog): def __init__(self, bot): self.bot = bot # 提取重复的消息检查逻辑 def _guess_check(self, ctx, msg): return msg.author == ctx.author and msg.channel == ctx.channel # 提取重复的猜数字循环逻辑 async def _run_guess_loop(self, ctx, range_min, range_max, attempts): await ctx.send( f"Now guess a number between **{range_min}-{range_max}**, you have **{attempts}** attempts. Type 'stop' to give up." ) entry_count = 0 target_num = random.randrange(range_min, range_max + 1) # 修正randrange,确保包含最大值 while entry_count < attempts: msg = await self.bot.wait_for('message', check=lambda m: self._guess_check(ctx, m)) entry_count += 1 if msg.content.lower() == "stop": await ctx.send(f"You gave up 😢") await ctx.send(f"The number was **{target_num}**") return # 处理非数字输入 try: user_guess = int(msg.content) except ValueError: await ctx.send(f"Please enter a valid number!") entry_count -= 1 continue if user_guess < range_min or user_guess > range_max: await ctx.send(f"Pick a number between **{range_min}-{range_max}**!") entry_count -= 1 elif user_guess == target_num: await ctx.send(f"**Good job, it was {target_num}!**") return else: await ctx.send(f"Nope, keep guessing", delete_after=2) # 用完所有尝试次数 await ctx.send(f"You ran out of inputs, it was **{target_num}**!") @commands.command() async def guess(self, ctx): try: await ctx.send( f"Pick a range of numbers you want and the number of attempts you want." f"Ex: '__**1-10**, **4**__' or '__**600-10**, **200**__'" ) # 等待用户输入范围和尝试次数 msg = await self.bot.wait_for('message', check=lambda m: self._guess_check(ctx, m)) num_list = re.findall(r'\d+', msg.content) # 验证输入格式 if len(num_list) != 3: await ctx.send("Invalid input! Please follow the format: 'min-max, attempts'") return range_1 = int(num_list[0]) range_2 = int(num_list[1]) attempts = int(num_list[2]) # 自动调整范围顺序 if range_1 > range_2: range_1, range_2 = range_2, range_1 # 启动猜数字循环 await self._run_guess_loop(ctx, range_1, range_2, attempts) except Exception as error: print(f"{error}") await ctx.send(f"Problem: **[{error}]**") # 注册Cog的标准函数(适配discord.py v2.x) async def setup(bot): await bot.add_cog(GuessCog(bot))
额外优化说明
- 新增输入验证逻辑,避免用户错误输入导致程序崩溃
- 提取重复代码模块,提升代码可读性和可维护性
- 修正
random.randrange参数,确保能取到范围最大值 - 使用
setup函数注册Cog,符合discord.py最新版本规范
内容的提问来源于stack exchange,提问作者Proxima
相关产品推荐
相关产品推荐

