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. Android中使用开源框架citypickerview实现省市区三级联动选择

    1.概述 记得之前做商城项目,需要在地址选择中实现省市区三级联动,方便用户快速的填写地址,当时使用的是一个叫做android-wheel 的开源控件,当时感觉非常好用,唯一麻烦的是需要自己整理并解析省 ...

  2. li点击弹出序号

    <body> <ul> <li>test1</li> <li>test2</li> <li>test3</li ...

  3. 常见的html面试题

    1.doctype作用?标准模式和兼容模式各有什么区别? (1).<doctype>声明位于文档第一行,在<html>标签之前.用于告知浏览器的解析器以什么样的标准解析该文档. ...

  4. Xamarin自定义布局系列——瀑布流布局

    Xamarin.Forms以Xamarin.Android和Xamarin.iOS等为基础,自己实现了一整套比较完整的UI框架,包含了绝大多数常用的控件,如下图 虽然XF(Xamarin.Forms简 ...

  5. 转换器4:手写PHP转Python编译器,语法解析部分

    写完词法部分,又有很多杂事,周末终于有空来实现伟大的语法解析部分了. 撸完代码之后发现,程序太短了,不算上状态机,才186行(含注释),关键代码不到100行.运行调试过后,发现还行.居然可以解析One ...

  6. node.js异步控制流程 回调,事件,promise和async/await

    写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...

  7. 基于Modbus的C#串口调试开发

    说明:本文主要研究的是使用C# WinForm开发的串口调试软件(其中包含Modbus协议相关操作).Modbus相关协议可以查阅百度文库等,可参考: <http://wenku.baidu.c ...

  8. BananaPi python-Mysql 操作库

    BananPi python-Mysql 操作库 1.首先mysql.python环境安装 2.下载MySQL-python-1.2.3.tar.gz 并解压 tar xfz MySQL-python ...

  9. Android中的几种多线程实现

    有以下几种方式: 1)Activity.runOnUiThread(Runnable) 2)View.post(Runnable) ;View.postDelay(Runnable , long) 3 ...

  10. 【转】Django HTTP请求的处理流程

    Django 和其他 Web 框架的 HTTP 处理的流程大致相同,Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的.我们可以在 Middlewar ...