如何调用库中带装饰器的函数?及简化库内实现方案
问题解答
问题1:如何调用自研库中被装饰器标记的函数?
在库内部的对应业务时机(比如连接建立完成、服务初始化就绪等),触发预先注册好的事件回调即可。核心是把被装饰器标记的函数统一存储,在需要执行的时候调用(支持单个或批量执行)。
问题2:简化库内带装饰器的函数调用实现
你当前用全局变量绑定单个回调的方式扩展性差(新增事件就要加新的全局变量和装饰器),可以用事件管理器类统一管理所有事件回调,实现更简洁且可扩展的逻辑,思路和Discord.py的@client.event一致:
简化后的库内部实现
import asyncio class EventManager: def __init__(self): # 用字典存储事件名与回调函数列表的映射 self._event_handlers = {} # 通用事件装饰器:支持指定任意事件名 def event(self, event_name): def decorator(func): # 初始化事件对应的回调列表(若不存在) self._event_handlers.setdefault(event_name, []) self._event_handlers[event_name].append(func) return func return decorator # 语法糖:针对常用事件单独定义装饰器,简化写法 def on_ready(self, func): return self.event("on_ready")(func) def on_connect(self, func): return self.event("on_connect")(func) # 触发事件的核心方法:执行对应事件的所有回调 async def trigger(self, event_name, *args, **kwargs): if event_name not in self._event_handlers: return # 遍历执行所有回调,兼容同步/异步函数 for handler in self._event_handlers[event_name]: if asyncio.iscoroutinefunction(handler): await handler(*args, **kwargs) else: handler(*args, **kwargs)
使用者的调用方式
# 实例化事件管理器,对应示例中的client client = EventManager() # 方式1:用语法糖装饰器注册事件 @client.on_connect def on_connect(): print("Connected!") # 方式2:用通用装饰器注册任意事件 @client.event("on_ready") async def on_ready(): print(f'{client} has connected to Discord!')
库内部触发事件的时机
在库的业务逻辑到达对应节点时,调用trigger方法即可:
# 比如连接建立完成时(同步事件直接调用) client.trigger("on_connect") # 比如服务就绪时(异步事件需要await) await client.trigger("on_ready")
优势对比
- 无需维护大量全局变量,所有事件回调统一存在字典中
- 新增事件只需添加语法糖方法,或直接用
@client.event("new_event")注册,扩展性极强 - 支持同时注册多个同事件的回调函数(比如多个
on_ready逻辑) - 自动兼容同步/异步回调函数
内容的提问来源于stack exchange,提问作者user19345539
相关产品推荐
相关产品推荐

