装饰器本质:就是函数,功能是为其他函数添加附加功能
装饰器原则:
-
<李>不修改被修饰函数的源代码李>
<李>不修改修饰函数的调用方式李>
装饰器的知识储备:
装饰器=高阶函数+函数嵌套+闭包
初识装饰器
先看一个需求:下面这个函数用来计算1到20的和
<代码> def calc (l): res=0 李:我的 time . sleep (0.01) res +=我 返回res 结果=calc(范围(21)) 打印(结果)代码>
但现在需求有变,不仅要计算1到20的和,还需要计算该函数运行的时间,此时装饰器就应需而生
<代码>导入时间 def计时器(函数): def包装器(* args, * * kwargs): start_time=time.time () res=func (* args, * * kwargs) stop_time=time.time () 打印(“函数运行的时间为:% s的% (stop_time - start_time)) 返回res 返回包装 @timer def calc (l): res=0 李:我的 time . sleep (0.01) res +=我 返回res 结果=calc(范围(21)) 打印(结果)代码>
运行结果如下:
<代码>函数运行的时间为:0.2048475742340088 210年代码>
上面的计时器函数就是calc函数的装饰器
高阶函数
高阶函数定义:
1。函数接收的参数是一个函数名
2。函数的返回值是一个函数名
3。满足上述条件任意一个,都可称之为高阶函数
高阶函数示例
<代码> def foo (): 打印(“我的函数名作为参数传给高阶函数”) def gao_jie1(函数): 打印('我就是高阶函数1,我接收的参数名是% s的%函数) 函数() def gao_jie2(函数): 打印('我就是高阶函数2,我的返回值是% s的%函数) 回归函数 gao_jie1 (foo) gao_jie2 (foo) 代码>
把函数当作参数传给高阶函数
<代码> #高阶函数应用1:把函数当做参数传给高阶函数 导入的时间 def foo (): 打印(“foo”) def timmer(函数): start_time=time.time () 函数() stop_time=time.time () 打印(“函数% s运行时间是% s的% (func stop_time-start_time)) 蒂莫(foo) #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer (foo),改变了函数的调用方式代码>
函数返回值是函数名
<代码> #高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名 导入的时间 def foo (): 打印(“foo”) def timmer(函数): start_time=time.time () 回归函数 stop_time=time.time () 打印(“函数% s运行时间是% s的% (func stop_time-start_time)) foo=timmer (foo) foo () #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能代码>
高阶函数总结
1。函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2。函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
函数嵌套
<代码> def父亲(名称): 打印(从父亲% s ' %名称) def的儿子(): print(“从子”) def的孙子(): 打印(从孙子”) 孙子() 儿子() 父亲(坡)代码>
闭包
<代码>” 闭包:在一个作用哉里放放定义变量,相当于打了一个包 ''' def父亲(名称): def的儿子(): 打印('我爸爸是% s ' %的名字) def的孙子(): 打印(爷爷是% s %名称) 孙子() 儿子() 父亲(坡)代码>
无参数装饰器
无参装饰器=高级函数+函数嵌套
基本框架
<代码>” 这就是一个实现装饰器最基本的架子 ''' def计时器(函数): def包装(): 函数() 返回包装()代码>
回到上面需要计算函数运行时间的需求,在不使用装饰器的情况下加上以下代码
<代码>导入时间 def计时器(函数): def包装(): 开始时间=time.time () 函数() stopTime=time.time () 打印(“函数运行时间为:% s的% (stopTime -开始时间)) 返回包装 def测试(): time . sleep (3) 打印(“测试函数运行完毕”) res=计时器(测试) res()python基础四:装饰器