python 模拟事件触发机制
EventManager.py
# -*- encoding: UTF-8 -*- # 系统模块
from queue import Queue, Empty
from threading import * class EventManager:
def __init__(self):
"""初始化事件管理器"""
# 事件对象列表
self.__eventQueue = Queue()
# 事件管理器开关
self.__active = False
# 事件处理线程
self.__thread = Thread(target = self.__Run) # 这里的__handlers是一个字典,用来保存对应的事件的响应函数
# 其中每个键对应的值是一个列表,列表中保存了对该事件监听的响应函数,一对多
self.__handlers = {} # {事件类型:[处理事件的方法]} def __Run(self):
"""引擎运行"""
while self.__active == True:
try:
# 获取事件的阻塞时间设为1秒
event = self.__eventQueue.get(block = True, timeout = 1)
self.__EventProcess(event)
except Empty:
pass def __EventProcess(self, event):
"""处理事件"""
# 检查是否存在对该事件进行监听的处理函数
if event.type_ in self.__handlers:
# 若存在,则按顺序将事件传递给处理函数执行
for handler in self.__handlers[event.type_]:
handler(event) def Start(self):
"""启动"""
# 将事件管理器设为启动
self.__active = True
# 启动事件处理线程
self.__thread.start() def Stop(self):
"""停止"""
# 将事件管理器设为停止
self.__active = False
# 等待事件处理线程退出
self.__thread.join() def AddEventListener(self, type_, handler):
"""绑定事件和监听器处理函数"""
# 尝试获取该事件类型对应的处理函数列表,若无则创建
try:
handlerList = self.__handlers[type_]
except KeyError:
handlerList = [] self.__handlers[type_] = handlerList
# 若要注册的处理器不在该事件的处理器列表中,则注册该事件
if handler not in handlerList:
handlerList.append(handler) def RemoveEventListener(self, type_, handler):
"""移除监听器的处理函数"""
#读者自己试着实现 def SendEvent(self, event):
"""发送事件,向事件队列中存入事件"""
self.__eventQueue.put(event) """事件对象"""
class Event:
def __init__(self, type_=None):
self.type_ = type_ # 事件类型
self.dict = {} # 字典用于保存具体的事件数据
test.py
# -*- encoding: UTF-8 -*- from threading import *
from EventManager import *
import time #事件名称 新文章
EVENT_ARTICAL = "Event_Artical" #事件源 公众号
class PublicAccounts:
def __init__(self,eventManager):
self.__eventManager = eventManager def WriteNewArtical(self):
#事件对象,写了新文章
event = Event(type_=EVENT_ARTICAL)
event.dict["artical"] = u'如何写出更优雅的代码\n'
#发送事件
self.__eventManager.SendEvent(event)
print(u'公众号发送新文章') #监听器 订阅者
class Listener:
def __init__(self,username):
self.__username = username #监听器的处理函数 读文章
def ReadArtical(self,event):
print(u'%s 收到新文章' % self.__username)
print(u'正在阅读新文章内容:%s' % event.dict["artical"]) """测试函数"""
def test():
listner1 = Listener("thinkroom") #订阅者1
listner2 = Listener("steve")#订阅者2 eventManager = EventManager() #绑定事件和监听器响应函数(新文章)
eventManager.AddEventListener(EVENT_ARTICAL, listner1.ReadArtical)
eventManager.AddEventListener(EVENT_ARTICAL, listner2.ReadArtical)
eventManager.Start() publicAcc = PublicAccounts(eventManager)
while True:
publicAcc.WriteNewArtical()
time.sleep(2) if __name__ == '__main__':
test()
python 模拟事件触发机制的更多相关文章
- 【深入浅出Linux网络编程】 “基础 -- 事件触发机制”
回顾一下“"开篇 -- 知其然,知其所以然"”中的两段代码,第一段虽然只使用1个线程但却也只能处理一个socket,第二段虽然能处理成百上千个socket但却需要创建同等数量的线程 ...
- C#事件触发机制
C#的事件触发机制,类似于c++的回调函数机制 我先简单说一下,委托和事件的实质,后期再重开一篇博文来详细说 委托:指向方法的指针,类似于C的函数指针 事件:是一个可以存放0个或多个方法指针的数据结构 ...
- EventEmitter:nodeJs事件触发机制
Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.r ...
- [转载] 理解 epoll 的事件触发机制
原文: http://weibo.com/p/1001603862394207076573?sudaref=weibo.com epoll的I/O事件触发方式有两种模式:ET(Edge Trigger ...
- html元素双击事件触发机制猜想及疑惑
今天有个同事遇到一个奇怪的问题,我照着他的代码做了一些简化写了这个demo <!DOCTYPE html> <html> <head> <style type ...
- WinForm中的事件触发机制学习
在一个Form窗体中拖个按钮,双击后系统自动生成代码: private void button1_Click(object sender, EventArgs e) { } 同时在窗体的Initial ...
- Yii中事件触发机制
控制器初始化中添加事件处理方法,在需要触发的地方直接触发 public function init() { parent::init(); // TODO: Change the autogenera ...
- 基于raw os 的事件触发系统
Raw os的事件触发系统有以下特点: 1 基于UML的状态机理念设计,实现了有限状态机(fsm)以及层次状态机(HSM). 2 实现了活动对象(ACTIVE OBJECT)的特性,一个活动对象包含了 ...
- JQuery的方便之处——宽高设置、坐标值和滚动条+事件绑定机制
1.元素的宽高 可以通过css来进行设置,例如:$("元素").css({"宽度":"值","高度":"值&q ...
随机推荐
- Java for LeetCode 109 Convert Sorted List to Binary Search Tree
Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...
- bind、call、apply的区别与实现原理
1.简单说一下bind.call.apply的区别 三者都是用于改变函数体内this的指向,但是bind与apply和call的最大的区别是:bind不会立即调用,而是返回一个新函数,称为绑定函数,其 ...
- BZOJ 3037 创世纪
题解: 首先从基环树上的环上选两个点x,y 断开x,y之间的边,然后做树形DP. 设f[x]为选x的情况下的最大值,g[x]为不选x的情况下的最大值. 分两种情况讨论, 1.选x,则y一开始就处于被支 ...
- echarts如何显示在页面上
echarts如何显示在页面上 1.引入echarts的相关.js文件 <script src="js/echarts.min.js"></script> ...
- [原创]java操作word生成水印
应用场景 为了保护版权或辨别文件的真伪,有时需要在生成的Word文件中动态添加水印,PageOffice组件的WaterMark类就封装了给在线编辑的Word文件添加水印这一功能,调用接口非常简单. ...
- Linux_服务器_02_在linux上怎么看eclipse控制台输出语句
在windows下,tomcat启动之后有一个黑窗口,很容易看到System.out.println或ex.printStackTrace这样的函数输出,非常方便调试,但是在linux下,没有这样的窗 ...
- listen 54
Our library is also open for the local residents. People are doing their Christmas shopping. Later t ...
- Unix环境编程之文件IO
1.文件IO 2.文件与目录 3.进程 4.多线程编程 5.信号 6.进程间通信 学习linux编程,首先要学会使用shell,这里一些基础命令就不介绍了.这里唯一要提的一个shell命令就是man. ...
- 多线程之:java的CAS操作的相关信息
一:锁机制存在的性能问题? 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁). 锁机制存在以下问题:(1)在多线程竞争下,加锁.释放锁会导 ...
- 【Lintcode】029.Interleaving String
题目: Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2 ...