彻底弄懂Python中的回调函数(callback)


Posted in Python onJune 25, 2022

摘要

主要是介绍python 的回调函数callback。

什么是回调函数

当程序运行是,一般情况下,应用程序会时常通过API调用库里所预先备好的函数。但是有些库函数却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)

例如:

有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)

可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。(我认为)这应该是回调最早的应用之处,也是其得名如此的原因。

彻底弄懂Python中的回调函数(callback)

回调机制的优势

回调机制提供了非常大的灵活性。我们把图中的库函数改称为中间函数了,这是因为回调并不仅仅用在应用和库之间。任何时候,只要想获得类似于上面情况的灵活性,都可以利用回调。有的同学可定想回调似乎只是函数间的调用,可以发现两者之间的一个关键的不同

在回调中,我们利用某种方式,把回调函数像参数一样传入中间函数。可以这么理解,在传入一个回调函数之前,中间函数是不完整的。换句话说,程序可以在运行时,通过登记不同的回调函数,来决定、改变中间函数的行为。这就比简单的函数调用要灵活太多了。

#回调函数1
#生成一个2k形式的偶数
def double(x):
    return x * 2
    
#回调函数2
#生成一个4k形式的偶数
def quadruple(x):
    return x * 4
 
callback_demo.py`
 
from even import *
 
#中间函数
#接受一个生成偶数的函数作为参数
#返回一个奇数
def getOddNumber(k, getEvenNumber):
    return 1 + getEvenNumber(k)
    
#起始函数,这里是程序的主函数
def main():    
    k = 1
    #当需要生成一个2k+1形式的奇数时
    i = getOddNumber(k, double)
    print(i)
    #当需要一个4k+1形式的奇数时
    i = getOddNumber(k, quadruple)
    print(i)
    #当需要一个8k+1形式的奇数时
    i = getOddNumber(k, lambda x: x * 8)
    print(i)
    
if __name__ == "__main__":
    main()

异步处理有关的回调函数

def apply_ascyn(func, args, callback):
    """ 
    func 函数的是处理的函数
    args 表示的参数
    callback 表示的函数处理完成后的 该执行的动作
    """
    result = func(*args)
    callback(result)
 
def add(x, y):
    return x + y
 
def print_result(result):
    print(result)
 
apply_ascyn(add, (2, 3), callback=print_result)

这里print_result只能接收一个result的参数,不能传入其他信息。当想让回调函数访问其他变量或者特定环境的变量值的时候会遇到问题。

使用一个绑定方法来代替这个简单函数。

def appy_async(func, args, *, callback):
    result = func(*args)
    #异步执行的函数 同时将执行后返回到这个早从这个函数跳出去
    callback(result)
 
def add(x ,y):
    return x + y
 
class ResultHandler(object):
    def __init__(self):
        self.sequence = 0
 
    def handle(self, result):
        self.sequence += 1
        print("[{}] Got: {}".format(self.sequence, result))
 
resultHandler = ResultHandler()
appy_async(add, (2,3), callback=resultHandler.handle)

彻底弄懂Python中的回调函数(callback)

 使用闭包代替上面的类来实现

def apply_async(func, args, *, callback):
    result = func(*args)
    callback(result)
 
def add(x ,y):
    return x + y
 
def make_handler():
    sequence = 0
    def handler(result):
        nonlocal sequence
        sequence += 1
        print("[{}] Got:{}".format(sequence, result))
    return handler
 
handler = make_handler()
apply_async(add, (2,3), callback=handler)

使用协程来完成异步操作

def apply_async(func, args, *, callback):
    result = func(*args)
    callback(result)
 
def add(x, y):
    return x + y
 
def make_handler():
    sequence = 0
    while True:
        result = yield
        sequence += 1
        print("[{}] Got:{}".format(sequence, result))
 
handle = make_handler()
next(handle)
 
apply_async(add, (2,3), callback=handle.send)

博文参考:

python3回调函数(callback) - 知乎

总结

到此这篇关于Python中回调函数(callback)的文章就介绍到这了,更多相关Python 回调函数callback内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Python 相关文章推荐
Python自动化测试工具Splinter简介和使用实例
May 13 Python
Python的Flask框架中实现登录用户的个人资料和头像的教程
Apr 20 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
Apr 28 Python
Python实现的密码强度检测器示例
Aug 23 Python
Python+Socket实现基于TCP协议的客户与服务端中文自动回复聊天功能示例
Aug 31 Python
Python实现查看系统启动项功能示例
May 10 Python
python环形单链表的约瑟夫问题详解
Sep 27 Python
Python实现的调用C语言函数功能简单实例
Mar 13 Python
pyqt5与matplotlib的完美结合实例
Jun 21 Python
Python 虚拟环境工作原理解析
Dec 24 Python
Python实现石头剪刀布游戏
Jan 20 Python
Python爬虫自动化爬取b站实时弹幕实例方法
Jan 26 Python
利用Python实现翻译HTML中的文本字符串
Jun 21 #Python
使用scrapy实现增量式爬取方式
Jun 21 #Python
python+opencv实现目标跟踪过程
Jun 21 #Python
使用opencv-python如何打开USB或者笔记本前置摄像头
Python+DeOldify实现老照片上色功能
Python使用Opencv打开笔记本电脑摄像头报错解问题及解决
Jun 21 #Python
virtualenv隔离Python环境的问题解析
Jun 21 #Python
You might like
PHP怎样调用MSSQL的存储过程
2006/10/09 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
精选的10款用于构建良好易用性网站的jQuery插件
2011/01/23 Javascript
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
node.js中的events.emitter.listeners方法使用说明
2014/12/10 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
Node.js实用代码段之正确拼接Buffer
2016/03/17 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
2016/09/01 Javascript
jQuery Dialog 打开时自动聚焦的解决方法(两种方法)
2016/11/24 Javascript
Vue中父组件向子组件通信的方法
2017/07/11 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
从vue源码看props的用法
2019/01/09 Javascript
详解javascript 变量提升(Hoisting)
2019/03/12 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
js实现html滑动图片拼图验证
2020/06/24 Javascript
JavaScript实现与web通信的方法详解
2020/08/07 Javascript
深入理解javascript中的this
2021/02/08 Javascript
Python虚拟环境virtualenv的安装与使用详解
2017/05/28 Python
python实现数据导出到excel的示例--普通格式
2018/05/03 Python
对python中的高效迭代器函数详解
2018/10/18 Python
更改Python的pip install 默认安装依赖路径方法详解
2018/10/27 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
Django+zTree构建组织架构树的方法
2019/08/21 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
python中property和setter装饰器用法
2019/12/19 Python
深入浅析HTML5中的article和section的区别
2018/05/15 HTML / CSS
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
Cecil Mode法国在线商店:女性时尚
2021/01/08 全球购物
庆祝国庆节标语
2014/10/09 职场文书
工程技术负责人岗位职责
2015/04/13 职场文书
护理培训心得体会
2016/01/22 职场文书
Python实现列表拼接和去重的三种方式
2021/07/02 Python
MySQL中order by的使用详情
2021/11/17 MySQL
java中为什么说子类的构造方法默认访问的是父类的无参构造方法
2022/04/13 Java/Android