闭包
所谓闭包,其实就是在子函数里面调用父函数的变量
def A(a):
def B():
print(a)
A("hello")
那这个特性有什么用呢?
举一个例子,当前有个函数add,参数是a和b,实现功能是a+b:
def add(a, b):
return a + b
在不允许修改函数add的情况下(不允许修改底层代码的情况在公司是常见的),要求我们定义一个函数add_a_10,参数只有一个,该函数功能是让参数和10相加并返回,那么普通做法我们可以这样:
def add_a_10(a):
return add(a, 10)
这个时候,产品经理凑到你耳边对你说:“只能加10吗?我们后面还需要加11、12、13的,你看着办吧”
???产品又该需求是吧?这个时候咱们就可以用闭包来做了:
def add_a_b(a):
def add_b(b):
return add(a, b)
return add_b
可以看到,在函数add_b里面调用了父函数add_a_b的变量a,调用add函数返回结果,而在父函数add_a_b的最后返回了该子函数对象add_b,也就是返回值是一个函数。那么,我们就可以随意定义产品经理所需要的函数:
add_10 = add_a_b(10) # 加10
add_11 = add_a_b(11) # 加11
add_12 = add_a_b(12) # 加12
print(add_10(5))
print(add_11(5))
print(add_12(5))
可以看到,上面定义了加10、11、12的3个函数。以后还有需要就简单一行定义即可
回调函数
回调函数其实简单来说就是将函数名作为参数传递
def hello():
print("hello world")
def callback(func):
func()
callback(hello)
那么,有什么应用呢?
这里还是举个例子。这个例子是关于多线程的,顺便让我们也了解一下如何定义和使用python中的多线程
from threading import Thread
from time import time
def printNow():
print(time())
if __name__ == '__main__':
# 创建两个线程
thread1 = Thread(target=printNow) # 创建线程,target参数指定调用的函数
thread2 = Thread(target=printNow)
# 开启线程
thread1.start() # start方法开启线程
thread2.start()
# 阻塞线程,等待结束
thread1.join()
thread2.join()
运行这段代码,会发现开启了两个线程并输出了时间戳。而我们在创建线程时传递的target=printNow
就是指定printNow
为线程的回调函数,线程对象调用start()方法时就会自动调用这个回调函数。通过这种方式,我们无需了解多线程的底层逻辑,只需要把函数名给它就行了。
至此,我们对回调函数也基本了解了。简单来说,回调函数有以下特点:
- 回调函数就是将函数名作为参数传递
- 回调函数相比普通传值,可以处理更复杂的任务。因此,在一些仅传递普通变量难以完成的任务中(比如多线程)常常使用回调函数
如果我的分享能帮助到你,那我的分享就多了一份意义;如果有错误的地方劳烦指出,期待共同进步!