关于回调函数,网上有很多说明和各种解释,多数在尝试用语言描述。我认为,如果对各个角色之间的关系不清楚,如果没有相关的编程需求,那么语言便非常无力,很难理解。

这是360百科的解释:

  在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序
  【什么是其它代码?什么是某一块?什么是可执行?什么是引用?什么是允许?什么是底层代码?什么是高层定义?什么是子程序?这些词,每一个词都有很多含义,如果你理解回调,那么这个定义描述得非常准确,如果你不理解回调,那么等于没说,文字都认识,连起来不知道啥意思。】

这是知乎的一个解释:

  https://www.zhihu.com/question/19801131

还有些用指针来进行说明

   如果一个人不知道回调,他很可能也不了解指针这个C语言中的核心。

一图解千言,一例解千言,下面是一个python中的回调函数例子,可能可以有效地说明什么是回调函数。这个栗子用于下载时展现下载进度。

urlretrieve(url, filename=None, reporthook=None, data=None)

这是urllib.request中的一个函数,用于直接将远程数据下载到本地。

  • url是你要下载的链接
  • 参数 finename 指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)
  • 参数 reporthook 是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度
  • 参数 data 指 post 到服务器的数据,该方法返回一个包含两个元素的(filename, headers)元组,filename 表示保存到本地的路径,header 表示服务器的响应头。

  注意看reporthook,现假设你作为一名使用Python做开发的程序员,你不是在为Python开发插件,而是在用现成的插件去实现你的功能,那么,Python语言和它的插件,整体上是封闭的,假设你看不到Python的源代码。

  此时,你要使用urlretrieve这个函数,分以下几种情况:

  1.你可以只用一个参数的,即urlretrieve(url),那么你只能把远程的链接所打开的页面存到本地这个单纯的动作,没有其它功能和反馈。

  2.除了查看那个实际下载的文件是否完成和在控制台中查看程序的执行结束以外,实际上你无法知道1的进度,也无法知道是否下载成功。那么,此时reporthook就有作用了,你需要给urlretrieve传一个你本地函数的名字,带着3个参数(假设这个函数是func(a,b,c),函数名是func),在你无法看到的urlretrieve内部,必要的时候,它会调用你传给它的这个函数(func),把合适的数据赋给这个func的3个参数,然后,你就可以在你本地处理这3个参数,比如,显示出来。

  这三个参数,按顺序分别表示:已经下载的数据块、数据块的大小、远程文件的大小,得到这几个数据,我们就可以得到下载的进度。

  以下是官方文档中的说明:

   If reporthook is given, it must be a function accepting three numeric parameters: A chunk number, the maximum size chunks are read in and the total size of the download (-1 if unknown). It will be called once at the start and after each chunk of data is read from the network. reporthook is ignored for local URLs.

来源:https://docs.python.org/3.6/library/urllib.request.html#module-urllib.request

以下是代码:

import urllib

def cbk(a, b, c): 

    '''回调函数
@a: 已经下载的数据块
@b: 数据块的大小
@c: 远程文件的大小
'''
per = 100.0 * a * b / c if per > 100:
per = 100
print('%.2f%%' % per) url = 'http://www.bing.com'
local = 'd://bing.html'
urllib.urlretrieve(url, local, cbk)

(以上代码来自http://www.nowamagic.net/academy/detail/1302861

这是你作为一个使用者,使用别人设计好的函数时的情况。

 

对于Python中回调函数的理解的更多相关文章

  1. java中回调函数的理解

    一,案例一 "通常大家说的回调函数一般就是按照别人(李四)的定好的接口规范写,等待别人(张三)调用的函数,在C语言中,回调函数通常通过函数指针来传递:在Java中,通常就是编写另外一个类或类 ...

  2. python中strip()函数的理解

    1.strip()函数 函数原型 声明:s为字符串.rm为要删除的字符序列 s.strip(rm) :删除s字符串中开头.结尾处.位于 rm删除序列的字符 s.lstrip(rm) :删除s字符串中开 ...

  3. 什么是工厂函数?Python 中工厂函数怎么理解?(转)

    所谓工厂函数就是指这些内建函数都是类对象(实际上是类), 当你调用它们时,实际上是创建了一个类实例. type():查看类型

  4. js中的回调函数的理解和使用方法

    js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...

  5. js中的回调函数的理解

    一,常见的但是不是特别注意的回调方法. 1.1,ajax $.ajax({ url:"test.json", type: "GET", data: {usern ...

  6. 回调函数透彻理解Java

    http://blog.csdn.net/allen_zhao_2012/article/details/8056665 回调函数透彻理解Java 标签: classjavastringinterfa ...

  7. js回调函数(callback)理解

    Mark! js学习 不喜欢js,但是喜欢jquery,不解释. 自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速google之,发现原来中文翻译成回调.也就是回调函 ...

  8. C++中回调函数(CallBack)的使用

    如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过. 其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而 ...

  9. JavaScript callback function 回调函数的理解

    来源于:http://mao.li/javascript/javascript-callback-function/ 看到segmentfault上的这个问题 JavaScript 回调函数怎么理解, ...

随机推荐

  1. Servlet入门总结及第一个Servlet程序

    目录 一了解Servlet的概念 二Servlet技术功能 三 Servlet技术特点 四 Servlet生命周期 五servlet工作过程 六 Servlet与JSP区别 七Servlet代码结构 ...

  2. 5 -- Hibernate的基本用法 --2 Hibernate入门

    5.2.1 Hibernate 下载和安装 5.2.2 Hibernate 的数据库操作 5.2.3 在Eclipse中使用Hibernate 啦啦啦

  3. [转]Struts2多个文件上传

    转载至:http://blog.csdn.net/hanxiaoshuang123/article/details/7342091 Struts2多个文件上传多个文件上传分为List集合和数组,下面我 ...

  4. Python 基础进阶

    函数的定义 函数的参数 函数的默认参数 函数的变量 函数的返回值 函数的多类型传值 函数的冗余参数 函数的递归调用 匿名函数 高阶函数 内建函数 模块与包 面向对象 类的定义 类的属性 类的内置属性 ...

  5. Splash resource_timeout 属性

    resource_timeout属性用于设置加载的超时时间,单位是秒,如果设置为 0 代表不检测超时,如下,设置超时时间为 0.1 秒: function main(splash) splash.re ...

  6. mybatis 之parameterType="Long"

    <select id="selectByPrimaryKeyByArrayMemberId" resultType="memberModel" param ...

  7. RabbitMQ之总结

    P:生成者,消息产生者: C:消息消费者: 红:消息队列: java实现 步骤: 创建连接 从连接中创建通道(相当于JDBC中的Statement) 通过channel声明(创建)队列.(如果队列存在 ...

  8. vue再次入手(数据传递②)

    接上篇~ 5.最后一种,互通:无所谓父组件或者是子组件,而是随时随地都能调用到数据的一种方法.便是利用vuex来管理数据,官网描述: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它 ...

  9. #pragma init_seg

    先进后出原则,最先初始化的最后析构! 1.C++中全局对象.变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用.对于不同文件中的全局对象.变量,它们的构造函数调用顺序是未定义的 ...

  10. 使用session防止表单进行重复提交

    我们都知道可以通过js的方法来实现防止表单重复提交,但是js只适用于“在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交” 的情况下进行操作, 那如果碰到“表单提交后用户点击[刷新 ...