回调函数是什么:
百度解释
回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、
ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。
回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求
必须要使用回调函数来实现。
最著名的回调函数调用有C/C++标准库stdlib.h/cstdlib中的快速排序函数qsort和二分查找函数bsearch
中都会要求的一个与strcmp类似的参数,用于设置数据的比较方法。
回调函数的机制
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
在C中回调函数是通过函数指针来实现的,再Python中,已经没有指针这个说法了,一般都是说函数名。简单来说就是定义一个函数,然后将这个函数的函数名传递给另一个函数做参数,以这个参数命名的函数就是回调函数。
def my_callbcak(args):
print(*args)
def caller(args, func):
func(args)
caller((1,2), my_callbcak)
结果:
# 1 2
其中:my_callback是回调函数,因为它作为参数传递给了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。
注意:这里print_result只能接收一个result的参数,不能传入其他信息。当想让回调函数访问其他变量或者特定环境的变量值的时候会遇到问题。
解决办法:
1、为了让回调函数访问外部信息,使用一个绑定方法来代替这个简单函数。
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))
r = ResultHandler()
appy_async(add, (2,3), callback=r.handle)
结果:
[1] Got: 5
2、使用闭包代替上面的类来实现
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)
结果:
[1] Got:5
3、使用协程
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 # yield实现协程
sequence += 1
print("[{}] Got:{}".format(sequence, result))
handle = make_handler()
next(handle)
apply_async(add, (2,3), callback=handle.send)
结果:
[1] Got:5
yield实现协程的内容参考另一篇文章:Python中的协程