python实现回调函数,自定义事件

最近一个项目,需要实现自定义事件,发现python对于事件好像没有一个非常标准的封装,或者是原语,下面是自己去实现的一个类似事件的方法,逻辑上参考了.net实现事件的方法,也就是特殊的委托。

1. python回调函数

如果对于python回调函数比较熟悉,可以跳过。

讲实话,论坛上基本上说的什么回调函数,只不过是把函数当做参数传递,这种方式也能称之为“回调”函数吗,可能是我浅薄了。。。

def funcA(a, b):
    return a + b

def funcB(a, b, c, func):
    return func(a, b) + c

if __name__ == '__main__':
    # 将funcA当做参数,传入funcB
    res = funcB(1, 2, 3, funcA)
    print(res)

说一下这个不能称之为回调函数的原因。回调函数应该是指一个函数指针,当我们调用这个函数指针的时候,相当于调用了指针所指向的函数。按上面的示例,一般将funcA称为回调函数,主函数的funcA相当于是函数指针,指向这个回调函数,并将这个“指针”当做参数传给了funcB。这样理解和操作是ok的,但是如果我在调用funcB的时候,并不知道这个指针指向的是哪个回调函数,我只知道这个函数需要的形参和返回值,那该如何操作。如果是c或者c++,可以声明函数指针,然后使用这个函数指针传进去,这个指针指向的是谁可能是由别的函数指定的,那这样的操作python该如何完成。

上面这一大段文字可能理解起来比较绕,没关系,这个和下面的自定义事件逻辑非常像。

2. python自定义事件

事件概述

如果熟悉.NET的话,应该非常清楚事件的机制,我做自定义事件也是参照这一逻辑处理的,可以自行跳过这一小节。

事件的拥有者:事件的发送者

事件的订阅者:事件的接受和处理

事件关系:事件发生后会不会得到响应,得到谁的响应

举个例子:

老师上课点名,点到小明的名字,小明答:到!其他人都没有吱声,其他课堂的人,包括也有一个叫小明的也没有吱声。

上面老师就是事件的拥有者,发出了点名的事件,所有课堂上的同学都订阅了这个事件。这个事件带有一个参数为姓名,姓名的值为小明,于是小明响应这个事件,并喊了一声到!其他课堂的人由于没有订阅这个事件,所以不会动作。

python实现自定义事件

现在有这样一个业务场景。开一个线程循环监视一个变量,当这个变量变化的时候,发出事件,报告这个变量变化了,同时携带一个参数,参数就是这个变量变化的值,之间的监听者响应这个事件。

import time
import threading

test = 18

class MyEvent:
    onVarChanged = []
    @staticmethod
    def raiseEvent(*args):
        for fun in MyEvent.onVarChanged:
            fun(*args)

def reportVarChange():
    currentVar = test
    while True:
        time.sleep(0.01)
        if test != currentVar:
            # test变量发生了改变,激发事假
            MyEvent.raiseEvent(test)
            currentVar = test

def ChangeProcessor(newVar):
    print("changed to:", newVar)

if __name__ == '__main__':
    # 订阅事件,并指定处理函数
    MyEvent.onVarChanged.append(ChangeProcessor)
    t = threading.Thread(target=reportVarChange)
    t.start()
    time.sleep(1)
    test = 20
    time.sleep(1)
    test = 80
    time.sleep(1)

熟悉.NET的人对这个框架可能就比较熟悉了,MyEvent类相当于是声明的委托,MyEvent.onVarChanged相当于实现委托的多播。主函数中对onVarChanged列表添加函数指针。当事件发生,MyEvent.raiseEvent函数被调用,所有onVarChanged中函数的指针都被调用。

这样的话,就可以做个EventBase的事件基类,所有自定义事件都继承这个类形成规范。

class EventBase:
    eventHandler = []
    @staticmethod
    def raiseEvent(obj, *args):
        for fun in EventBase.eventHandler:
            fun(obj, *args)

其中raiseEvent参数obj就是发出事件的对象,*args就是事件参数

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值