python使用装饰器实现的事件中心(监听器)

其中GroupMessage,FriendMessage就是两个python类
@evn.on(GroupMessage)与evn.trigger(GroupMessage, 'arg1', 'arg2')
里面传的GroupMessage代表事件名为<class 'mirai.models.events.GroupMessage'>作为字典的键

import functools
from mirai import GroupMessage,FriendMessage
class Event:
def __init__(self, name, func):
# 初始化事件对象,包含事件名称和对应的函数
self.name = name
self.func = func
class EventCenter:
def __init__(self):
# 初始化一个字典来存储事件名称和对应的事件列表
self.__listeners = {}
@property
def on(self):
# 返回一个装饰器工厂
def add(event_name):
def decorator(func):
@functools.wraps(func) # 应用于wrapper函数
def wrapper(*args, **kwargs):
# 执行被装饰的函数
return func(*args, **kwargs)
# 创建Event对象并注册事件监听器
event = Event(event_name, wrapper)
self.addListener(event)
return wrapper # 返回wrapper函数,它现在是一个装饰器
return decorator
return add
def addListener(self, event: Event):
# 添加事件监听器到对应的事件名称下
event_name = self.__listeners.get(event.name)
if event_name is None:
self.__listeners[event.name] = [] # 如果事件名称不存在,初始化一个空列表
self.__listeners[event.name].append(event.func) # 添加函数到对应的列表
def removeListener(self, event: Event):
# 移除事件监听器
if event.name in self.__listeners:
self.__listeners[event.name].remove(event.func)
def trigger(self, event_name, *args, **kwargs):
# 触发事件
event_funcs = self.__listeners.get(event_name)
if event_funcs:
for func in event_funcs:
func(*args, **kwargs)
evn = EventCenter()
@evn.on(GroupMessage)
def fun(x, y):
# 定义事件1对应的函数
print("group message", x, y)
@evn.on(FriendMessage)
def fun2(x, y):
# 定义事件2对应的函数
print("member message", x, y)
# 触发事件,预期输出 "aaa arg1 arg2" 和 "bbb arg1 arg2"
evn.trigger(GroupMessage, 'arg1', 'arg2')
evn.trigger(FriendMessage, 'arg1', 'arg2')
# 再次添加相同的函数到事件1
@evn.on(GroupMessage)
def fun3(x, y):
"""方法三"""
print("group message again", x, y)
# 再次触发事件1,预期会看到两次输出,因为添加了两个不同的函数到同一个事件
evn.trigger(GroupMessage, 'arg1', 'arg2')
# 并且输出方法也正确
f = evn.on(FriendMessage)(fun3)
print(f.__name__)
print(f.__doc__)
# 移除事件
evn.removeListener(Event(GroupMessage,fun3))
# 再次触发事件 就只会触发一次了
evn.trigger(GroupMessage, 'arg1', 'arg2')

最后输出
group message arg1 arg2
member message arg1 arg2
group message arg1 arg2
group message again arg1 arg2
fun3
方法三
group message arg1 arg2

posted @   Excel2016  阅读(26)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示