1、递归函数
在函数内部,可以调用其他函数,如果一个函数在内部调用自己本身,就是递归函数,
例:数字每次除2,直到不能除为止,(取整数)
1 # 数字每次除2,直到不能除为止,(取整数) 2 def calc(num): 3 print(num) 4 if int(num/2) > 0: 5 return calc(int(num/2)) 6 print("--->",num) 7 calc(20)
执行结果:
递归函数特性:
1、必须要有一个明确的结束条件
2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)
2、嵌套函数
在一个函数体内用def声明一个新的函数,而不是调用
1 def where (): 2 print("where?") 3 def bar(): 4 print("in the bar") 5 bar() #在where这一级 6 where()
理解嵌套函数和函数的调用的区别:
1 #嵌套函数 2 def foo(): 3 print("in the foo") 4 def bar(): #函数嵌套,在一个函数中通过def定义另一个函数。 5 print("in the bar") 6 bar() #bar函数只能在这里调用,bar是局部变量,只在foo函数中生效。 7 foo() 8 9 # 函数调用 10 def test2(): 11 print("in the test2") 12 def test1(): 13 print("in the test1") 14 test2() #这里就是函数的调用,非函数的嵌套。 15 test1()
执行结果:
3、高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数。
1、把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
2、返回值中包含函数名(不修改函数的调用方式)
例1:把一个函数名当做实参传给另一个函数
1 # 第一个标准定义高阶函数:把一个函数名当做实参传给另一个函数,可以实现不改变被装饰函数的源代码 2 import time 3 def bar(): 4 time.sleep(3) 5 print("in the bar") 6 def test1(func): 7 start_time = time.time() 8 func() 9 stop_time = time.time() 10 print("the func run time is %s" %(stop_time-start_time)) 11 12 test1(bar)
执行结果:
小结:
上面案例实现不改变被装饰函数的源代码
例2:返回值中包含函数名
1 # 按照第二种方式定义高阶函数:返回值中包含函数名 2 import time 3 def bar(): 4 time.sleep(3) 5 print("in the bar") 6 def test2(func): 7 print(func) 8 return func 9 #将test3()定义一个变量,是为了后面好调用,t其实就是一个返回值func(内存地址) 10 # t=test2(bar) #func=bar=bar的函数体(内存地址) 11 # t() 12 #为了实现不改变调用方式,将上面的t变为bar,覆盖bar的值.这样就实现了调用方式不改变。 13 bar = test2(bar) 14 bar()
执行结果:
小结:
上面案例 没有修改函数的调用方式。