Python回调函数用法实例详解


Posted in Python onJuly 02, 2015

本文实例讲述了Python回调函数用法。分享给大家供大家参考。具体分析如下:

一、百度百科上对回调函数的解释:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

二、什么是回调:

软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础,因此,下面我们着重讨论回调机制在不同软件架构中的实现。

三、一个小例子:

#call.py 
import called 
def callback(): 
  print "in callback" 
def main(): 
  #called.test() 
  called.test_call(callback) 
  print "in call.py" 
main() 
#called.py 
''''' 
def test(): 
  print "in called.py test()" 
''' 
def test_call(p_call): 
  print "in called.py test_call()" 
  p_call() 
joe@joe:~/test/python$ python call.py 
in called.py test_call() 
in callback 
in call.py 
joe@joe:~/test/python$

网上搜到的一个面向对象实现的例子:

当你要加入回调(Callback)功能的时候,代码往往会偏重于回调的实现而不是问题本身了。一个解决方法就是实现一个通用的基础类来解决回调的需求,然后再来实现你为某个事件(Event)所绑定(Binding)的方法(Method)。

代码如下:

class CallbackBase: 
  def __init__(self): 
 self.__callbackMap = {} 
 for k in (getattr(self, x) for x in dir(self)): 
   if hasattr(k, "bind_to_event"): 
 self.__callbackMap.setdefault(k.bind_to_event, []).append(k) 
   elif hasattr(k, "bind_to_event_list"): 
 for j in k.bind_to_event_list: 
   self.__callbackMap.setdefault(j, []).append(k) 
  ## staticmethod is only used to create a namespace 
  @staticmethod 
  def callback(event): 
 def f(g, ev = event): 
   g.bind_to_event = ev 
   return g 
 return f 
  @staticmethod 
  def callbacklist(eventlist): 
 def f(g, evl = eventlist): 
   g.bind_to_event_list = evl 
   return g 
 return f 
  def dispatch(self, event): 
 l = self.__callbackMap[event] 
 f = lambda *args, **kargs: \ 
   map(lambda x: x(*args, **kargs), l) 
 return f 
## Sample 
class MyClass(CallbackBase): 
  EVENT1 = 1 
  EVENT2 = 2 
  @CallbackBase.callback(EVENT1) 
  def handler1(self, param = None): 
 print "handler1 with param: %s" % str(param) 
 return None 
  @CallbackBase.callbacklist([EVENT1, EVENT2]) 
  def handler2(self, param = None): 
 print "handler2 with param: %s" % str(param) 
 return None 
  def run(self, event, param = None): 
 self.dispatch(event)(param) 
if __name__ == "__main__": 
  a = MyClass() 
  a.run(MyClass.EVENT1, 'mandarina') 
  a.run(MyClass.EVENT2, 'naranja')

这里有一个类,它有两个事件(EVENT1和EVENT2)和两个处理函数(handler)。第一个处理函数handler1注册了EVENT1,而第二个处理函数handler2当EVENT1或者EVENT2发生的时候都会执行(即注册了全部的事件)。

运行函数(run)在MyClass的主循环中,它会将对应的事件派送(dispatch)出去。这(这里指dispatch函数)会返回一个函数,我们可以把所有需要传给这个函数的参数列表传给它。这个函数运行结束会返回一个列表(list),列表中是所有的返回值。

也许,使用Metaclass能够实现的更优雅一些吧。

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
用实例分析Python中method的参数传递过程
Apr 02 Python
python使用筛选法计算小于给定数字的所有素数
Mar 19 Python
使用pandas中的DataFrame数据绘制柱状图的方法
Apr 10 Python
Python绘制的二项分布概率图示例
Aug 22 Python
使用OpenCV实现仿射变换—旋转功能
Aug 29 Python
python子线程退出及线程退出控制的代码
Oct 16 Python
Python TCPServer 多线程多客户端通信的实现
Dec 31 Python
python3 正则表达式基础廖雪峰
Mar 25 Python
Keras - GPU ID 和显存占用设定步骤
Jun 22 Python
Python getattr()函数使用方法代码实例
Aug 10 Python
一文搞懂python异常处理、模块与包
Jun 26 Python
利用python做数据拟合详情
Nov 17 Python
在Python中marshal对象序列化的相关知识
Jul 01 #Python
python保存字符串到文件的方法
Jul 01 #Python
python选择排序算法实例总结
Jul 01 #Python
python实现的希尔排序算法实例
Jul 01 #Python
python获取一组汉字拼音首字母的方法
Jul 01 #Python
python的keyword模块用法实例分析
Jun 30 #Python
Python实现监控程序执行时间并将其写入日志的方法
Jun 30 #Python
You might like
PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
2018/12/08 PHP
JavaScript 序列化对象实现代码
2009/12/18 Javascript
jquery.validate使用攻略 第一部
2010/07/01 Javascript
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
2010/10/20 Javascript
读jQuery之六 缓存数据功能介绍
2011/06/21 Javascript
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
js简单的点击返回顶部效果实现方法
2015/04/10 Javascript
浅谈NodeJS中require路径问题
2015/05/07 NodeJs
javascript中判断json的方法总结
2015/08/27 Javascript
JS运动相关知识点小结(附弹性运动示例)
2016/01/08 Javascript
Javascript技术栈中的四种依赖注入详解
2016/02/23 Javascript
JavaScript获取IP获取的是IPV6 如何校验
2016/06/12 Javascript
关于微信中a链接无法跳转问题
2016/08/02 Javascript
javascript字符串对象常用api函数小结(连接,替换,分割,转换等)
2016/09/20 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
2017/06/13 jQuery
javascript中的隐式调用
2018/02/10 Javascript
JavaScript生成指定范围的时间列表
2018/03/19 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
关于vue的列表图片选中打钩操作
2020/09/09 Javascript
详解Vue.js3.0 组件是如何渲染为DOM的
2020/11/10 Javascript
[02:27]《DAC最前线》之附加赛征程
2015/01/29 DOTA
[49:17]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第三场 1月26日
2021/03/11 DOTA
Python爬虫实现(伪)球迷速成
2018/06/10 Python
python实现决策树分类
2018/08/30 Python
Python 中的lambda函数介绍
2018/10/10 Python
Python使用pandas对数据进行差分运算的方法
2018/12/22 Python
python实现生成Word、docx文件的方法分析
2019/08/30 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
2020/04/24 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
中国宠物用品商城:E宠商城
2016/08/27 全球购物
澳大利亚拥有最佳跳伞降落点和最好服务的跳伞项目运营商:Skydive Australia
2018/03/05 全球购物
西部世纪面试题
2014/12/05 面试题
高级技校毕业生自荐信
2013/11/18 职场文书
自我评价正确写法范文
2013/12/10 职场文书
2015年预防青少年违法犯罪工作总结
2015/05/22 职场文书
JavaWeb 入门篇(3)ServletContext 详解 具体应用
2021/07/16 Java/Android