之前写代码遇到这个问题已经少,也没有去深究,都是拿来即用。
今天在《python+cookbook中文第三版》中看到了这个问题,做下笔记,以便以后查阅。
回调函数是什么:
以上来自百度百科
在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
sequence += 1
print("[{}] Got:{}".format(sequence, result))
handle = make_handler()
next(handle)
apply_async(add, (2,3), callback=handle.send)
结果:
[1] Got:5