Python事件驱动模式简单理解

所有的计算机程序都可以大致分为两类:脚本型(单次运行)和连续运行型(直到用户主动退出)。
(1)脚本型:脚本型的程序包括最早的批处理文件以及使用Python做交易策略回测等等,这类程序的特点是在用户启动后会按照编程时设计好的步骤一步步运行,所有步骤运行完后自动退出。
(2) 连续运行型:连续运行型的程序包含了操作系统和绝大部分我们日常使用的软件等等,这类程序启动后会处于一个无限循环中连续运行,直到用户主动退出时才会结束。
我们要开发的交易系统就是属于连续运行型程序,而这种程序根据其计算逻辑的运行机制不同,又可以粗略的分为时间驱动和事件驱动两种。

1.1 时间驱动

时间驱动的程序逻辑相对容易设计,简单来说就是让电脑每隔一段时间自动做一些事情。这个事情本身可以很复杂、包括很多步骤,但这些步骤都是线性的,按照顺序一步步执行下来。
时间驱动的程序本质上就是每隔一段时间固定运行一次脚本。尽管脚本自身可以很长、包含非常多的步骤,但是我们可以看出这种程序的运行机制相对比较简单、容易理解。
时间驱动的程序在量化交易方面还存在一些其他的缺点:如浪费CPU的计算资源、实现异步逻辑复杂度高等等。

import time


def demo():
    print('do some thing ... ')


while True:
    demo()
    time.sleep(1.0)

1.2 事件驱动

与时间驱动对应的就是事件驱动的程序:当某个新的事件被推送到程序中时,程序立即调用和这个事件相对应的处理函数进行相关的操作。
举个例子:有些人喜欢的某个公众号,然后去关注这个公众号,哪天这个公众号发布了篇新的文章,没多久订阅者就会在微信里收到这个公众号推送的新消息,如果感兴趣就打开来阅读。
上面公众号例子可以翻译为,监听器(订阅者)监听了(关注了)事件源(公众号),当事件源的发送事件时(公众号发布文章),所有监听该事件的监听器(订阅者)都会接收到消息并作出响应(阅读文章)。
公众号为事件源订阅者为事件监听器订阅者关注公众号,相当于监听器监听了事件源公众号发布文章这个动作为发送事件订阅者收到事件后,做出阅读文章的响应动作。
事件驱动主要包含以下元素和操作函数:

1.2.1 元素

事件源
事件监听器
事件对象

1.2.2 操作函数

监听动作
发送事件
调用监听器响应函数
举例代码实现公众号订阅:

import time
from queue import Queue, Empty
from threading import *


class Event:
    """事件"""
    def __init__(self, type_=None):
        self.type_ = type_      # 事件类型
        self.dict = {}          # 字典用于保存具体的事件数据


class EventManager:
    """事件管理器"""
    def __init__(self):
        # 事件对象列表 可以使用队列或者是列表
        self.__eventQueue = Queue()
        # 事件管理器开关
        self.__active = False
        # 事件处理线程
        self.__thread = Thread(target=self.__run)
        # count 变量是用来便于观察执行的顺序
        self.count = 0
        # 这里的__handlers是一个字典,用来保存对应的事件的响应函数 其中每个键对应的值是一个列表,列表中保存了对该事件监听的响应函数,一对多
        self.__handlers = {}

    def __run(self):
        print('{}_run'.format(self.count))
        while self.__active is True:
            try:
                event = self.__eventQueue.get(block=True, timeout=1)
                self.__event_process(event)
            except Empty:
                pass
            self.count += 1

    def __event_process(self, event):
        """依次执行注册了回调"""
        print('{}_EventProcess'.format(self.count))
        # 检查是否存在对该事件进行监听的处理函数
        if event.type_ in self.__handlers:
            # 若存在,则按顺序将事件传递给处理函数执行
            for handler in self.__handlers[event.type_]:
                handler(event)
        self.count += 1

    def start(self):
        print('{}_Start'.format(self.count))
        # 将事件管理器设为启动
        self.__active = True
        # 启动事件处理线程
        self.__thread.start()
        self.count += 1

    def stop(self):
        """停止"""
        print('{}_Stop'.format(self.count))
        # 将事件管理器设为停止
        self.__active = False
        # 等待事件处理线程退出
        self.__thread.join()
        self.count += 1

    def add_event_listener(self, type_, handler):
        """绑定事件和监听器处理函数"""
        print('{}_AddEventListener'.format(self.count))

        # 尝试获取该事件类型对应的处理函数列表,若无则创建
        try:
            handlerList = self.__handlers[type_]
        except KeyError:
            handlerList = []

        self.__handlers[type_] = handlerList
        # 若要注册的处理器不在该事件的处理器列表中,则注册该事件
        if handler not in handlerList:
            handlerList.append(handler)
        print(self.__handlers)
        self.count += 1

    def remove_event_listener(self, type_, handler):
        """移除监听器的处理函数"""
        print('{}_RemoveEventListener'.format(self.count))
        try:
            handlerList = self.__handlers[type_]
            # 如果该函数存在于列表中,则移除
            if handler in handlerList:
                handlerList.remove(handler)
            # 如果函数列表为空,则从引擎中移除该事件类型
            if not handlerList:
                del self.__handlers[type_]
        except KeyError:
            pass
        self.count += 1

    def send_event(self, event):
        """向队列中存入事件 """
        print('{}_SendEvent'.format(self.count))
        self.__eventQueue.put(event)
        self.count += 1


# 时间名称 新文章
EVENT_ARTICAL = "Event_Artical"


# 事件源 公众号
class PublicAccounts:
    def __init__(self, eventManager):
        self.__eventManager = eventManager

    def write_newartical(self):
        # 事件对象 写了新文章
        event = Event(type_=EVENT_ARTICAL)
        # 事件数据
        event.dict["artical"] = u'如何写出更优雅的代码\n'
        # 发送事件
        self.__eventManager.send_event(event)
        print(u'公众号发送新文章\n')


class Listener:
    # 监听器 订阅者
    def __init__(self, username):
        self.__username = username

    def read_artical(self, event):
        # 监听器的处理函数 读文章
        print(u'%s 收到新文章' % self.__username)
        print(u'正在阅读新文章内容:%s' % event.dict["artical"])


def have_a_test():
    # 实例化监听器
    listner1 = Listener("thinkroom")  # 订阅者1
    listner2 = Listener("steve")      # 订阅者2

    # 实例化事件操作函数
    event_manager = EventManager()

    # 绑定事件和监听器响应函数(新文章)
    event_manager.add_event_listener(EVENT_ARTICAL, listner1.read_artical)
    event_manager.add_event_listener(EVENT_ARTICAL, listner2.read_artical)
    # 启动事件管理器
    event_manager.start()

    publicAcc = PublicAccounts(event_manager)

    # Timer(2, publicAcc.WriteNewArtical).start()

    for i in range(10):
        publicAcc.write_newartical()
        time.sleep(10)

    event_manager.stop()


if __name__ == '__main__':
    have_a_test()

转载

转自

https://blog.csdn.net/brucewong0516/article/details/84031715

有部分修改。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Python有很多GUI库可供选择,包括Tkinter、PyQt、wxPython等,不同的GUI库适用于不同的开发需求和风格。 其中,Tkinter是Python自带的GUI库,使用简单,适合初学者入门。PyQt则是一个功能强大的GUI库,支持跨平台,有着丰富的文档和示例,但学习曲线较陡峭。wxPython也是跨平台的GUI库,基于C++编写,具有强大的可定制性和灵活性。 下面是一个简单的Tkinter GUI界面设计示例: ```python import tkinter as tk # 创建主窗口 root = tk.Tk() # 设置窗口标题 root.title("My GUI") # 设置窗口大小 root.geometry("400x300") # 创建Label组件 label = tk.Label(root, text="Hello, world!") label.pack() # 创建Button组件 button = tk.Button(root, text="Click me!") button.pack() # 进入主循环 root.mainloop() ``` 这段代码创建了一个简单的GUI界面,包括一个Label组件和一个Button组件。你可以根据自己的需求自定义界面布局和组件。 ### 回答2: Python GUI界面设计是利用Python编程语言以及相关的GUI库和框架来创建用户界面的过程。Python提供了一些流行的GUI库,例如Tkinter、PyQt、wxPython等,使开发者能够轻松创建具有图形用户界面的应用程序。 Python GUI界面设计的优点之一是它的简洁性和易用性。Python提供了简洁的语法和丰富的库,使得开发者能够快速构建用户友好的应用程序。其语法易于理解,使得代码的编写和维护更加容易。 另一个优点是Python GUI界面设计的跨平台性。由于Python是一种跨平台的编程语言,开发的应用程序可以在不同的操作系统上运行,如Windows、Mac OS和Linux等。这使得开发者能够在各种平台上进行开发,并为用户提供统一的使用体验。 Python GUI界面设计还具有丰富的功能和灵活性。Python提供了许多GUI库和框架,这些库和框架提供了各种功能模块和工具,使开发者能够轻松实现按钮、标签、文本框、下拉菜单等常见的GUI组件。开发者也可以根据自己的需求自定义GUI组件,并结合其他Python库来实现更复杂的功能。 最后,Python GUI界面设计还具有较好的可扩展性和可维护性。由于Python具有清晰的结构和易于理解的语法,开发者可以更好地组织和管理代码。此外,Python的丰富的库和模块也使得开发者能够轻松地扩展和维护已有的应用程序。 总之,Python GUI界面设计是使用Python编程语言和相关GUI库创建用户友好的应用程序的过程。它的简洁性、跨平台性、功能丰富性以及可扩展性和可维护性使得它成为一种受欢迎的GUI开发方式。 ### 回答3: Python的GUI界面设计是通过使用各种GUI库来实现的,其中最常用的是Tkinter。下面我将简要介绍Python GUI界面设计的一些主要特点和用法。 首先,Python的GUI界面设计可以创建各种元素,如窗口、按钮、标签、文本框等。这些元素可以通过设定属性来自定义样式和行为。 其次,Tkinter提供了丰富的布局管理器,如Grid、pack和place。通过这些管理器,可以方便地调整元素在窗口中的位置和大小。 另外,Python的GUI界面设计支持事件驱动编程模式。通过绑定事件和编写相应的事件处理函数,可以实现响应用户操作的功能。例如,当用户点击按钮时,可以执行相应的操作。 此外,Python的GUI界面设计可以与其他Python库和模块进行集成。例如,可以使用matplotlib库在GUI界面中绘制图表,使用requests库进行网络请求,使用sqlite3库进行数据库操作等。 最后,Python的GUI界面设计也支持多线程编程。通过创建新的线程,可以在GUI界面中执行耗时操作,以避免界面的卡顿和不响应。 总之,Python的GUI界面设计提供了丰富的功能和灵活的使用方式,使开发者能够轻松地创建各种交互式的图形界面应用程序。无论是简单的小工具还是复杂的应用程序,Python都提供了足够的工具和库来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值