一 回调函数
简单来说:回调函数就是把函数当成一个参数传递到函数中.
def wake_call(time):
#第一种叫醒服务
print(time,"使用夺命电话连环call叫醒主人")
def wake_water(time):
#第二种叫醒服务
print(time,"使用早起泼冷水的方式叫醒主人")
def call_wake(time, func_name):
# 这个很重要,这个就是酒店服务业务的系统业务
#这是实现回调函数的核心
# time :预约时间
# func_time:回调函数名
# return :调用的函数的结果
return func_name(time)
#调用函数
#wake_call 被调用的函数就是回调函数
call_wake("凌晨7点", wake_call)
拓展: 编程分为两大类:系统编程和应用编程,所谓的系统编程简单来说就是编写库,而应用编程就是利用写好的各种库来编写具体的某种功能的程序,也就是应用. 系统程序员会在自己写的库中留下API(应用编程接口),以供应用程序员使用.【程序具有高内聚,低耦合】
当程序跑起来,一般情况下,应用程序会时常通过API调用库中所预备好的函数,但是有些库函数却要求应用先给它传递一个函数,好在合适的时候调用,以完成目标,这个被传入的后来又被调用的函数称为回调函数
二 返回函数
函数作为返回值
在python中除了可以接受函数作为参数外,还可以把函数作为结果值返回.
需求:实现一个可变参数的求和.通常是这么定义的:
def calc_sum(*args):
sum = 0
for i in args:
sum += i
return sum
现在需求有变,现在我不需要立即求和,而是在后面的代码中,根据需要再进行计算,这时候,我们可以不返回求和的结果,而是返回求和的函数.
def lazy_sum(*args):
def calc_sum():
sum = 0
for i in args:
sum += i
return sum
return calc_sum
当我们调用lazy_sum()时,返回的并不是求和的结果而是求和的函数
>>> f = lazy_sum(1, 2, 3, 4)
>>> f
<function lazy_sum.<locals>.calc_sum at 0x101b61598>
这时候调用f时,才真正计算求和的结果
>>> f()
10
像如上的函数,我们在函数lazy_sum中又定义了函数calc_sum,并且内部函数calc_sum可以使用lazy_sum的参数和局部变量,当lazy_sum返回函数calc_sum时,相关的参数以及变量都保存在返回的函数中,这种称为"闭包"
注意:当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数.
三 闭包
若在一个函数内部定义了另一个函数,外部的我们暂且称之为外函数,内部的称之为内函数
**闭包:**在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包
一般情况下,如果一个函数结束,函数内部所有的东西都会被释放掉,还给内存,局部变量也会消失,但是闭包是一种特殊的情况,如果外函数在结束的时候发现有自己的临时变量将来还会在内部函数中用到,就把这个临时变量绑定给了内函数,然后再自己结束.
#外函数, a与b都是临时变量
def outer(a):
b = 10
#内函数
def inner():
#在内函数中用到了外函数的临时变量
print(a+b)
#外函数的返回值是内函数的引用
return inner
# 调用函数传入参数5
f = outer(5)
f()
#结果
15
在函数外访问函数内的东西.闭包也具有提高代码可复用性的作用。闭包有效的减少了函数所需定义的参数数目
四 递归函数
递归函数:在函数的内部,可以调用其他的函数,如果一个函数在内部调用自身本身,这个函数就是递归函数.
递归调用:一个函数调用自身,成为递归函数
需求:计算n! = 1x2x3x4x…x(n-1)xn
使用递归解决问题的思路
方法:
1.写出临界条件
2.找这一次和上一次的关系
3.假设当前函数已经能用,调用自身计算上一次的结果,再求出本次的结果
# 关系: n!= (n-1)!xn
def fact(n):
#临界条件
if n==1:
return 1
#返回本次的调用结果
return n*fact(n-1)
递归函数的优点是定义简单,逻辑清晰,理论上所有的递归函数都可以写成循环的方式,但是循环的逻辑不如递归清晰.
注意:使用递归函数需要注意防止栈溢出,在计算机中函数是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,就会增加一层栈帧,每当函数返回,栈就会减一层栈帧,栈的大小是有限制的,所以当调用的次数过多的时候,会导致栈溢出
求斐波那契数列:1,1,2,3,5,8,13,21,34,55,89…
需求:报一个数,直接获取这个位置上的数值
#关系 第n个位置上的数值=(n-1)+(n-2)
#临界值 第一个位置和第二个位置的值为1
def func1(n):
if n==1 or n==2:
#临界值
return 1
else:
#返回本次调用的结果
return func1(n-1) + func1(n-2)