100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > python实现回调函数 自定义事件

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

时间:2019-07-22 02:21:00

相关推荐

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

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

1. python回调函数

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

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

def funcA(a, b):return a + bdef funcB(a, b, c, func):return func(a, b) + cif __name__ == '__main__':# 将funcA当做参数,传入funcBres = funcB(1, 2, 3, funcA)print(res)

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

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

2. python自定义事件

事件概述

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

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

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

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

举个例子:

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

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

python实现自定义事件

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

import timeimport threadingtest = 18class MyEvent:onVarChanged = []@staticmethoddef raiseEvent(*args):for fun in MyEvent.onVarChanged:fun(*args)def reportVarChange():currentVar = testwhile True:time.sleep(0.01)if test != currentVar:# test变量发生了改变,激发事假MyEvent.raiseEvent(test)currentVar = testdef ChangeProcessor(newVar):print("changed to:", newVar)if __name__ == '__main__':# 订阅事件,并指定处理函数MyEvent.onVarChanged.append(ChangeProcessor)t = threading.Thread(target=reportVarChange)t.start()time.sleep(1)test = 20time.sleep(1)test = 80time.sleep(1)

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

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。