思考下:
1、函数里面可以再定义函数,那函数里面定义的函数可以在外面调用吗?
2、函数里面可以自身调用自身吗?
1、闭包
1.1、闭包定义
闭包是函数里面嵌套函数,外层函数返回内层函数,这种情况称之为闭包
1.2、闭包与嵌套函数的区别
1.2.1、嵌套函数
def func():
def func1():
return "hello"
return func1() #返回值是func1函数值
print(func())
'''执行结果:hello'''
1.2.2、闭包
def func():
def func1():
return "hello"
return func1 #返回值是func1函数
a = func(' world')
print(a)
print(a()) #相当于函数再次调用
'''执行结果:<function func.<locals>.func1 at 0x0000000001E57DC0>'''
'''执行结果:hello'''
def func(x):
def func1():
return "hello" + x
return func1 #返回值是func1函数
a = func(' world')
print(a)
print(a()) #相当于函数再次调用
'''执行结果:<function func.<locals>.func1 at 0x0000000001E57DC0>'''
'''执行结果:hello world'''
闭包必须是嵌套函数,外层函数返回内层函数的引用(函数名),内层函数调用外部函数的变量
闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用
闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁
2、递归
递归中可以函数自身调用自身,但是使用时类似于条件循环一样,要有递归的终止条件
def func():
print("我要疯了")
func()
func()
'''会一直打印“我要疯了”
直至内存溢出,然后报错'''
以阶乘为例:
#阶乘
def factorial(n): #提示:n<=998
if n > 1:
return n * factorial(n-1)
else:
return 1
print(factorial(-10)) '''执行结果:1'''
print(factorial(1)) '''执行结果:1'''
print(factorial(5)) '''执行结果:120'''
同理,计算斐波拉切数列之和
#斐波拉切数列之和
def fn(n):
if n==0 or n==1:
return n
else:
return fn(n-1)+fn(n-2)
print(fn(10))
'''执行结果:55'''
使用递归时,常常可以让代码更加简洁
递归会占用比较多的内存,当递归次数比较多时,性能就会降低, 因此不建议多使用递归
3、回调
回调函数: 自身是一个函数,只是被传入到另一个函数当中,供其调用
def choice(play, ch):
if ch:
play()
else:
print('OK')
def play():
print('hahahaha')
choice(play,'') #这里仅0、()、[]、{}、''、""、False、None才会执行else
'''执行结果:hahahaha'''
#回调函数主要用于事件驱动模型、23种设计模式——观察者模式
回调函数不一定会被调用,是否调用由被传入函数的内部逻辑决定
思考题:
定义一个函数,传入一个字典和一个元组,
在字典key值不变的情况下,将字典的value值和元组的值交换,返回交换后的字典和与元组