彻底弄懂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中一些自然语言工具的使用的入门教程
Apr 13 Python
简述Python中的面向对象编程的概念
Apr 27 Python
python爬虫获取京东手机图片的图文教程
Dec 29 Python
python实现将读入的多维list转为一维list的方法
Jun 28 Python
pycharm安装和首次使用教程
Aug 27 Python
python模块导入的细节详解
Dec 10 Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 Python
python如何运行js语句
Sep 09 Python
利用django创建一个简易的博客网站的示例
Sep 29 Python
paramiko使用tail实时获取服务器的日志输出详解
Dec 06 Python
Python虚拟环境virtualenv创建及使用过程图解
Dec 08 Python
Python中Schedule模块使用详解 周期任务神器
Apr 19 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下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
PHP多进程编程实例详解
2017/07/19 PHP
在多个页面使用同一个HTML片段《续》
2011/03/04 Javascript
ASP.NET jQuery 实例15 通过控件CustomValidator验证CheckBoxList
2012/02/03 Javascript
整理AngularJS中的一些常用指令
2015/06/16 Javascript
深入分析node.js的异步API和其局限性
2016/09/05 Javascript
jQuery 特性操作详解及实例代码
2016/09/29 Javascript
JS判断是否为JSON对象及是否存在某字段的方法(推荐)
2016/11/29 Javascript
原生js实现电商侧边导航效果
2017/01/19 Javascript
关于jQuery中fade(),show()起始位置的一点小发现
2017/04/25 jQuery
Angular 4依赖注入学习教程之简介(一)
2017/06/04 Javascript
JavaScript栈和队列相关操作与实现方法详解
2018/12/07 Javascript
js中值引用和地址引用实例分析
2019/06/21 Javascript
原生js实现密码强度验证功能
2020/03/18 Javascript
vue element和nuxt的使用技巧分享
2021/01/14 Vue.js
[49:31]TFT vs Mski Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
Python打包可执行文件的方法详解
2016/09/19 Python
200行自定义python异步非阻塞Web框架
2017/03/15 Python
Python File readlines() 使用方法
2018/03/19 Python
python实现批量按比例缩放图片效果
2018/03/30 Python
flask框架单元测试原理与用法实例分析
2019/07/23 Python
基于python实现的百度音乐下载器python pyqt改进版(附代码)
2019/08/05 Python
python 通过手机号识别出对应的微信性别(实例代码)
2019/12/22 Python
python 生成正态分布数据,并绘图和解析
2020/12/21 Python
植物选择:Botanic Choice
2017/02/15 全球购物
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
艺术设计专业个人求职信范文
2013/12/11 职场文书
优秀部门获奖感言
2014/02/14 职场文书
企业精细化管理实施方案
2014/03/23 职场文书
体育比赛口号
2014/06/09 职场文书
博士生导师推荐信
2014/07/08 职场文书
行政司机岗位职责
2015/04/10 职场文书
开学典礼校长致辞
2015/07/29 职场文书
实习感想范文
2015/08/10 职场文书