EventManager事件管理类实现,大概就百来行代码左右。如果有不了事件驱动的工作原理的可以看前一篇《事件驱动的简明讲解》

# 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 = {}          # 字典用于保存具体的事件数据

测试代码

#-------------------------------------------------------------------
# encoding: UTF-8
import sys
from datetime import datetime
from threading import *
from EventManager import *

#事件名称  新文章
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'公众号发送新文章\n'

#监听器 订阅者
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)
    timer = Timer(2, publicAcc.WriteNewArtical)
    timer.start()

if __name__ == '__main__':
    test()

事件驱动的Python实现的更多相关文章

  1. 【循序渐进学Python】15.网络编程

    Python 内置封装了很多常见的网络协议的库,因此Python成为了一个强大的网络编程工具,这里是对Python的网络方面编程的一个简单描述. 1. 常用的网络设计模块 在标准库中有很多网络设计相关 ...

  2. python总结

    环境:django,numpy,matplotlib, 解释语言:开发效率高,通用性强,内置方便的数据容器,易于扩展和嵌入. 语言:lua--嵌入式/网络/APP,erlang--嵌入式,python ...

  3. Python之路Day9

    摘要: 协程 Select\Poll\Epoll异步IO与事件驱动 Python连接MySQL数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko Twsited网络 ...

  4. 2013年最好的Python开源项目汇总

    2013年Python社区诞生了很多实用的开发工具,这些工具 在一定程度上 可以帮助你节省更多的时间.本文为你汇总了这些工具,它们大部分都是开源的,你还可以通过源码来学习更多的Python开发知识. ...

  5. python 全栈开发,Day137(爬虫系列之第4章-scrapy框架)

    一.scrapy框架简介 1. 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前S ...

  6. 【转】Python爬虫(6)_scrapy框架

    官网链接:https://docs.scrapy.org/en/latest/topics/architecture.html 性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下 ...

  7. Python之爬虫总结

    一.爬虫之requests a.介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3)     b.注意:re ...

  8. python基础教程总结13——网络编程,

    1.网络设计模块 1.1 socket模块    根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. 1)服务器监听:是服务器端套接 ...

  9. 《Python基础教程读书笔记》

    第1章 快速构造:基础知识 1.2交互式构造器 不强制分号,一行就是一行.可以加上分号 1.4数字和表达式 加.减.乘.除.整除.求余.指数.取反(-例如-2**2,**的优先级比-大) from _ ...

随机推荐

  1. [C#7] 1.Tuples(元组)

    1. 老版本代码 class Program { static void Main(string[] args) { var fullName = GetFullName(); Console.Wri ...

  2. smarty模板做人员表信息删除,修改 里面的性别单选按钮民族下拉,另外登录进去可以显示姓名

    首先登录进去可以显示姓名 smarty模板做人员表信息删除,删除的时候有提示框确定删除吗. 修改 里面的性别单选按钮,要修改谁有默认选中,用了变量调节器 民族位置做下拉,用<{foreach}& ...

  3. 3408: [Usaco2009 Oct]Heat Wave 热浪

    3408: [Usaco2009 Oct]Heat Wave 热浪 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 67  Solved: 55[Subm ...

  4. 1257: [CQOI2007]余数之和sum

    1257: [CQOI2007]余数之和sum Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 2001  Solved: 928[Submit][Sta ...

  5. .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)

    序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令. Redis使用的是客户端-服务器模型和请求/响应协议的T ...

  6. Linux命令语句秘籍

    系统管理命令 stat              显示指定文件的详细信息,比ls更详细 who               显示在线登陆用户 whoami          显示当前操作用户 host ...

  7. 用js写倒计时,向列表添加数据-------2017-03-21

    一.单选按钮确定提交是否可用 <input id="a" type="radio" name="a"  onclick="c ...

  8. Linux块设备驱动(二) _MTD驱动及其用户空间编程

    MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...

  9. Excel制作多选下拉框代码以及图示

    1.首先  点击Sheet1(需要显示多选框的页) ,然后右键查看代码,进入编辑界面 2.写入如下代码 Private Sub Worksheet_SelectionChange(ByVal Targ ...

  10. 安装vnc远程连接CentOS桌面

    1.查看本机是否有安装vnc(centOS5默认有安装vnc) rpm -q vnc vnc-server 如果显示结果为: package vnc is not installedvnc-serve ...