如何将discord.py函数作为回调传入非discord.py类?
如何将discord.py函数传入非discord.py类作为回调函数
场景与问题
现有一个需要调试回调的类MyClass,代码如下:
class MyClass: def __init__(self, callback): self.callback = callback self.say_hello() self.say_goodbye() def say_hello(self): self.callback("hello") def say_goodbye(self): self.callback("goodbye")
计划用于调试的discord.py异步函数:
async def debug(ctx, msg): await ctx.send(msg)
当前存在两个关键问题:
MyClass调用回调时仅传递消息内容,无法提供discord.py所需的ctx上下文参数- discord.py函数为异步类型,但
MyClass是同步调用回调,直接传入会导致异步函数无法正确执行
解决方案
核心思路
通过包装函数解决两个问题:
- 用闭包或偏函数预先绑定
ctx,让包装后的回调函数匹配MyClass所需的参数格式(仅接收msg) - 在包装函数中调度异步任务,让discord.py的异步函数能在事件循环中正常执行
具体实现
方案1:闭包绑定ctx并调度异步任务
import asyncio from discord.ext import commands # 初始化bot(需根据实际需求配置intents) bot = commands.Bot(command_prefix='!', intents=commands.Intents.default()) @bot.command() async def trigger_myclass(ctx): # 定义闭包,将ctx预先绑定 def debug_callback(msg): # 利用asyncio将异步函数加入discord事件循环 asyncio.create_task(debug(ctx, msg)) # 将闭包传入MyClass作为回调 MyClass(debug_callback) async def debug(ctx, msg): await ctx.send(f"调试消息:{msg}") # 运行bot(替换为你的token) bot.run("YOUR_BOT_TOKEN")
方案2:使用functools.partial绑定ctx
如果更偏好显式的参数绑定,可以用functools.partial:
import asyncio from functools import partial from discord.ext import commands bot = commands.Bot(command_prefix='!', intents=commands.Intents.default()) @bot.command() async def trigger_myclass(ctx): # 绑定ctx到debug函数,生成仅需msg的偏函数 bound_debug = partial(debug, ctx) # 包装成同步回调,调度异步任务 def debug_callback(msg): asyncio.create_task(bound_debug(msg)) MyClass(debug_callback) async def debug(ctx, msg): await ctx.send(f"调试消息:{msg}") bot.run("YOUR_BOT_TOKEN")
额外说明
- 如果
MyClass是第三方无法修改的类,上述方案完全适用;若有权修改MyClass,也可以将其改造为支持异步回调(比如让say_hello和say_goodbye变为异步方法,直接await self.callback(msg)),但包装法更通用。 - 所有触发
MyClass的操作必须放在discord.py的命令或事件处理函数中,这样才能获取到有效的ctx上下文。
内容的提问来源于stack exchange,提问作者klg
相关产品推荐
相关产品推荐

