装饰器: 本质是函数, 功能是为其他函数添加附加功能
原则:
1 不修改被修饰函数的源代码
2 不修改被修饰函数的调用方式
为了实现装饰器的功能,需要了解3个概念
1。高阶函数
高阶函数定义
函数接收的参数是一个函数名
函数的返回值是一个函数名
满足上述条件的任意一个,都称为高阶函数
def foo(): print('from the foo') def test(func): return func res = test(foo)
res()
函数test()就是高阶函数, 因为其输入的参数就是foo函数名, 返回的也是func指示的foo的函数名
需要指出的是:
res()实际上就是foo()
我可以把 res = test(foo) ==> foo = test(foo)
嵌套函数
指的是在函数内在创建一个函数
def father(name): #print('from father%s' %name) def son(): #print('我的爸爸是%s'%name) def grandson(): #name='就是我自己' print('my grandfather%s'%name) return grandson return son father('abc')()()#my grandfather abc
运行一次函数返回内层嵌套函数的函数名在此运行(),又返回其内层的函数名再次运行(),把最内层的print出来
函数嵌套的目的很简单:
把参数传递给最里层的函数,并运行最里层函数 --实际上就是闭包的概念
整个的装饰器的原理和实现已经完成了!
装饰器的功能实现由4个内容的实现
1。运行被装饰的函数
2。传递被装饰函数的参数
3。返回被装饰函数的返回值
4。 在语法糖上输入各种可以传入的参数,以实现功能的增强
import time def timmer(func): def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print('程序test运行时间%s' % (stop_time - start_time)) return res return inner def test(name): time.sleep(1) print('%s test is over'%name) return True
以上就是装饰器的简单程序。 目前需要执行程序,为了实现装饰的调用不变的要求
test = timmer(test)
test()
需要分两步走,第一步获得inner函数的地址,赋值给test 然后运行test ,第二步运行test实际上是运行了inner函数, 在inner函数内的真实test的地址得到运行。
从而实现功能
把test =timmer (test ) ===> @ timmer来修饰test, 使得test () 更加真实还原!!!
import time def timmer(func): def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print('程序test运行时间%s' % (stop_time - start_time)) return res return inner @timmer # test = timmer(test) def test(name): time.sleep(1) print('%s test is over'%name) return True test('alex')
运行结果:
alex test is over 程序test运行时间1.0000572204589844