函数的递归
定义
"""
递归是指函数在执行过程中调用了本身。简单来说就是自己调用了自己
1.自己调用自己
2.一定要有一个条件,进行退出调用
"""
代码
"""
递归是指函数在执行过程中调用了本身。简单来说就是自己调用了自己
1.自己调用自己
2.一定要有一个条件,进行退出调用
"""
"""
阶乘:
比如说给一个数据5,阶乘5*4*3*2*1
n = 5*(5-1)
n =n*(4-1)
n =n*(3-1)
n =n*(2-1)
总结规律
n! = n*(n-1)
"""
def func_jc(n):
if n==1:
return 1
else:
return n*func_jc(n-1)
print(func_jc(5)) #120
流程
练习
练习一
"""
大家来写一个阶加
n= 5
5+4+3+2+1
"""
练习二
"""
下标 0,1,2,3,4,5,6
斐波那契数列:1,1,2,3,5,8,13。。。。
规律是:后一个数值等于前两个数值的和
f(0) = 1
f(1) = 1
f(2) = 1+1 = f(0)+f(1)
f(3) = 1+2 = f(1)+f(2)
打印斐波那契序列,
输入下标n=3 输出斐波那契序列3
"""
"""
函数递归
"""
def func_fb(n):
if n==0 or n==1:
return 1
else:
return func_fb(n-2)+func_fb(n-1)
print(func_fb(5) ) #8
"""
非递归
#下标是从0开始的
"""
def func(n):
#初始化两个变量
a,b=1,1
#range(5) ---->0,1,2,3,4
for i in range(n):
a,b=b,a+b
return a
print(func(5)) #8
效率的比较
"""
我能用普通函数写出来,为什么非要学递归,
"""
import time
"""
函数递归
"""
def func_fb(n):
if n==0 or n==1:
return 1
else:
return func_fb(n-2)+func_fb(n-1)
"""
非递归
#下标是从0开始的
"""
def func(n):
#初始化两个变量
a,b=1,1
#range(5) ---->0,1,2,3,4
for i in range(n):
a,b=b,a+b
return a
#perf_counter 以秒为单位进行记时间
start01 = time.perf_counter()
func_fb(10)
stop01= time.perf_counter()
print("递归函数的调用时间 %s" %(stop01-start01))
#process_time 以秒为单位进行记时间
start02 = time.perf_counter()
func(10)
stop02= time.perf_counter()
print("非递归函数的调用时间%s"%(stop02-start02))
"""
递归函数的调用时间 5.050000000000193e-05
非递归函数的调用时间7.3000000000017495e-06
"""
装饰器
定义
"""
1.装饰器是一个函数
2.装饰器是一个 为函数添加新的属性 的函数
3.通过闭包对函数添加新的属性
"""
语法
"""
语法
1.def func_a() #带有新特新的闭包函数
@def func_a
2.def func_b() #被修饰的函数
相当于func_a(func_b)
可以是多个@,如果是多个@的话,从下往上运行
"""
代码1
"""
1.装饰器是一个函数
2.装饰器是一个 为函数添加新的属性 的函数
3.通过闭包对函数添加新的属性
闭包函数:函数的子函数就是闭包函数
"""
#装饰器
def zhuangxiudui(a):
#闭包函数
def zhuangxiufangan():
print("贴瓷砖")
a()
print("隔音棉")
return zhuangxiufangan
@zhuangxiudui
def qiang():
print("来看看,就是这三面强")
#16-18行相当于 zhangxiudui(qiang)
#把qiang作为参数,传给了装修队这个函数
@zhuangxiudui
def men():
print("我是门")
"""
22-24行代表 zhangxiudui(men)
"""
#一周之后我来验货,来看看强弄好了没
qiang()
"""
贴瓷砖
来看看,就是这三面强
隔音棉
"""
代码2
#装饰器
def zhuangxiudui(a):
#闭包函数
def zhuangxiufangan():
print("贴瓷砖")
a()
print("隔音棉")
return zhuangxiufangan
def gaojizhuangxidui(b):
def zhuangxiufangan():
#你现在的墙是由瓷砖由隔音棉
b()
print("拆除瓷砖")
print("拆除隔音棉")
print("刷粉漆")
return zhuangxiufangan
"""
本来把墙给装修队,结果他装修坏了,我有找了一个高级装修队,进行重新装修
gaojizhuangxiudui(zhuangxiudui(qiang))
b=zhuangxiudui(qiang)
a=qiang
"""
@gaojizhuangxidui
@zhuangxiudui
def qiang():
print("来看看,就是这三面强")
qiang()
"""
贴瓷砖
来看看,就是这三面强
隔音棉
拆除瓷砖
拆除隔音棉
刷粉漆
"""
执行流程
练习
"""
闭包函数
定义个自己,
在定义一个幻想的子函数,在现女友函数前面,你有一个有气质的前女友,
但是现在你在想以后会不会找一个有钱的富婆,
定义一个现女友函数,现女友用行动告诉你,你想死吗
"""
Wraps()函数
定义
"""
1. @wraps(gaoyuanyuan) 保留高圆圆这个函数的所有属性和方法
2. from functools import wraps
Wraps(被修饰的物体) 保留被修饰物体的属性和函数
Wraps(化妆师(男人)) 保留性别这个属性
"""
代码
from functools import wraps
def ziji(gaoyuanyuan):
@wraps(gaoyuanyuan)
def huanxiang():
print("有一个有气质的前女友")
gaoyuanyuan()
print("找个富婆,有私房钱")
return huanxiang
@ziji
def gaoyuanyuan():
print("我是高圆圆,长得好看,但是脾气不好")
#gaoyuanyuan()
#__name__ 是个属性,可以拿到函数的名字,在调用的时候函数不要加()
"""
高圆圆的名字变成"自己",就是说gaoyuanyuan这个函数变成了huangxiang这个函数名字
这就意味这,我们使用@的时候,吧修饰函数(ziji)中的属性和函数给了被修饰物体(gaoyuanyaun)
女朋又也是有灵魂的,你强制把你的思想给女朋友
"""
"""
1. @wraps(gaoyuanyuan) 保留高圆圆这个函数的所有属性和方法
2. from functools import wraps
"""
print(gaoyuanyuan.__name__) #gaoyuanyuan
函数中有参数
定义
"""
1.通过闭包函数进行传参
2.万能参数:参数可以是任何数据类型,也可以是多个参数
*args,**kwargs
"""
代码
import time
#定义一个装饰器
#1.注意作为参数传递不能使用(n)
def youhua(func_fb):
#通过闭包函数,把n给闭包函数
def jisuanshijian(*a,**b):
start01 = time.perf_counter()
func_fb(*a,**b) #这里函数调用就可以有参数了
stop01 = time.perf_counter()
print("函数调用的时间是",(stop01-start01))
return jisuanshijian
#斐波那契数列
@youhua
def func_fb(n):
if n ==0 or n==1:
return 1
else:
return func_fb(n-1)+func_fb(n-2)
#函数调用的时间是 1.3999999999986246e-06
func_fb(1)
练习
"""
需求:
定义一个权限函数,传入一个name
定义一个装饰器,作用:用来判断权限函数的name是不是root
定义一个闭包函数,获取name,判断name是不是root,是的话有权限,不是的话没权限
#提示: 如何返回函数的实参?
inspect.getcallargs(函数名,参数):以字典的形式返回函数的参数 ( {形参:实参} )
get方法:返回字典指定key的value值
"""