在函数内部,可以调用其它函数,如果一个函数在内部调用自身本身,这个函数就是递归函数
递归特性:1.必须有一个明确的结束条件
2.每次进入更深一层递归时,问题规模比上次递归都有所减少(10-8-5等)
3.递归效率不高,递归层次过多会导致栈溢出,(计算机中,函数调用时通过栈(stack堆)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,函数返回栈就会减一层栈帧,由于栈的大小不是无限的,所以递归调用次数过度,会导致栈溢出)
默认最大的递归层数是999层
import sys
sys.setrecursionlimit(1500) # (recursion,递归,)(limit,限制,),导入sys修改最大递归数
def calc(n):#计算,
print(n)
return calc(n+1)
calc(0)
def calc(n):
print(n)
if int(n/2)>0:#如果n除以2大于0那就不断递归
return calc(int(n/2))
print('--->',n)
calc(10)#将10传进去
斐波拉契
#斐波拉契数列(Fibonaccl):除第一个和第二个数外,任意一个数都可以由前两个数相加得到(1.1.2.3.5.8.13.21.34....)
def fib(max):#10,斐波拉契数列从小往大推
n,a,b=0,0,1
while n<max:#n<10
print(b)
a,b=b,a+b#a,b重新赋的值,1,2=2,1+2
n=n+1
return 'done'
fib(10)
![](https://images2018.cnblogs.com/blog/1385785/201806/1385785-20180605212745836-1251670058.png)
作业:
写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者
def f5(depth,a1,a2):
if depth == 10:
return a1
a3 = a1+a2
r = f5(depth + 1,a2,a3)
return r
ret = f5(1,0,1)
print(ret)
装饰器
Décorator,装饰器也叫语法糖
1. 装饰器:本质是函数,是由def(装饰其它函数)就是为其它函数添加附加功能
原则:1.不能修改被装饰的函数的源代码(因为程序已经在运行了)
2.不能修改被装饰的函数的调用方式
实现装饰器知识储备:1.函数即‘变量’(函数也可以和变量一样通过赋值的方式调用,他们在内存中储存的方式是一致的)
2.高阶函数(a.把一个函数名当做实参传给另外一个函数【在不修改被装饰函数源代码的情况下为其添加功能】b.返回值中包含函数名【不修改函数的调用方式】)
3.嵌套函数(在一个函数里用def去申明一个新的函数)
高阶函数+嵌套函数=》装饰器
def outer_0(func):
def inner(*args,**kwargs):
print('3.5')
ret = func(*args,**kwargs)
print('789')
return ret
return inner
def outer(func):#最外层需要装饰的函数
def inner(*args,**kwarge):
print('123')
ret = func(*args,**kwarge)#获取的是旧函数index的值
print('456')
print(ret)
return ret
return inner
@outer_0
@outer#只要函数定义装饰器,那么def index()函数就会被重新定义:重新定义为装饰器的内层函数def inner
def index(a1,a2):#执行outer将index做为参数传递,将outer返回值重新赋值给index
print('好难')
return a1 + a2
index(1,2)
@outer
def f1(a1,a2,a3):#装饰器装饰带有参数的函数,一个函数可以应用多个装饰器.
print('f1')
return 'f1'
f1(1,2,3)
装饰带有参数的函数内部调用关系:
![](https://images2018.cnblogs.com/blog/1385785/201806/1385785-20180605212951695-1570372698.jpg)
![](https://images2018.cnblogs.com/blog/1385785/201806/1385785-20180605213013693-1823151147.png)
Import time
![](https://images2018.cnblogs.com/blog/1385785/201806/1385785-20180605213059450-1621689960.png)
@timmer
![](https://images2018.cnblogs.com/blog/1385785/201806/1385785-20180605213127344-455660745.png)
装饰器案例
import time#0
def timer(func):#1,3,timer(test1) , func=test1,func=test2高阶函数
def deco(*args,**kwargs):#4,7,嵌套函数
start_time=time.time()#8,
func(*args,**kwargs)#9,
stop_time=time.time()#13,
print('the func run time is %s'%(stop_time-start_time))#14,
return deco#5,返回这个函数的内存地址
@timer,2,10,test1=timer(test1) ,没有调用变量的赋值动作
def test1():
time.sleep(1)#11,
print('in the test1')#12,
@timer#test2=timer(test2),test2=deco,test2()=deco()
def test2(name,age):
time.sleep(1)
print('test2',name,age)
test1()#6,->deco
test2('zhangchao',29)
装饰器高级案例
user,passwd='alex','abc123'
def auth(auth_type):
print('outer func:', auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs): # (wrapper包装)
print('wrapper func args:',*args,**kwargs)
if auth_type=='local':
username = input('username:').strip()
password = input('password:').strip()
if user == username and passwd == password:
print('