python中的callback

1,541 阅读2分钟

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

callback 是什么

callback是回调函数 - 通过函数指针调用的函数。python中没有指针的说法,其实也就是定义一个函数,把这个函数名当作另一个函数的参数。这个用参数命名的函数就叫作回调函数 - 通过函数参数传递到其他的代码。传过去的这块代码也是一个被封装好的函数,只不过把它当作参数来使用。

为什么需要callback

为什么需要callback,我的理解就是,让库函数更加灵活。
程序可以分为两大类 - 系统编程和应用编程。这个说法太抽象了。其实就是说,我们在编程的过程中会自己写一些程序实现某个功能,这个叫应用程序。但在写程序过程中,有一些比较复杂或者通用的方法,就封装成库,我们只需要调用库函数使用,这个就是系统编程。
那么callback是干嘛的呢。callback实际上就是系统编程和应用编程之间的桥梁。用网上比较通用的一个例子 - 起床叫醒服务:系统编程会提供叫醒服务。但用什么方式叫醒,就可以通过回调函数定义。这样要实现起床叫醒服务,不同的人就可以按照自己定义的不同方法来实现。这就使得库函数能够被很灵活的应用了。
否则用闹钟叫醒封装成一个库函数,用手机铃声叫醒再封装成一个,需要的库函数可就太多啦。

具体实现。

def my_callbcak(args):
    print(*args)

def caller(args, func):
    func(args)

caller((1,2), my_callbcak)

结果:
# 1 2

caller是一个函数,my_callbcak就是回调函数,因为它被当作caller中的参数来使用。

异步处理的回调函数。

def apply_ascyn(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)

结果:
5

print_result 只能接收一个result参数,传递其他参数就会出问题。为了使回调函数能够访问外部信息

  • 用闭包代替上面的类
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)