前言:本节主要学习装饰器
一、装饰器
定义:本质上是个函数,用来装饰其他函数;(就是为其他函数添加附加功能)
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
以上两点可以总结出装饰器对被装饰的函数来说是完全透明的,因为装饰器不能修改原函数的源代码,被装饰的函数还是像往常一样继续运行。
实现装饰器的知识储备:1.函数即‘变量’
2.高阶函数
3.嵌套函数
可以理解成:高阶函数 + 嵌套函数 = 装饰器
1.函数即‘变量’
内存回收机制:数据存储在内存中,用变量名来引用;如果把内存比作一栋大厦,数据比作一个房间,变量名相当于门牌号,用门牌号来访问房间;如果删除了变量名,在一段时间内没有引用数据,python的内存回收机制就会回收数据。
函数如同变量:函数和变量一样也有内存回收机制,在定义函数的时候相当于把函数体赋值给了函数名,在内存里面存储着函数体,然后用函数名来引用;匿名函数也是一样,在内存中存储lambda表达式,如果把lambda表达式赋值给一个变量名,就能用变量来引用lambda表达式。
2.高阶函数
满足下面任意一条就可以看做是高阶函数:
a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b:返回值中包含函数名(不修改函数的调用方式)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:qinjiaxi 4 import time 5 6 def bar(): 7 time.sleep(3) 8 print('in the test1') 9 10 def test1(func): 11 start_time = time.time() 12 func() 13 stop_time = time.time() 14 print("time func run time is %s" % (stop_time-start_time)) 15 16 test1(bar)
3.嵌套函数
在一个函数体内定义一个函数,而不是在一个函数里面调用函数,这个叫做函数的嵌套。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:qinjiaxi 4 x = 2 5 def grandpa(): 6 x = 1 7 def father(): 8 x = 2 9 def son(): 10 x = 3 11 print(x) 12 son() 13 father() 14 grandpa()
返回值是3
4.装饰器实例
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:qinjiaxi 4 import time 5 #timer是装饰器满足嵌套函数(函数里面定义一个函数),满足高阶函数(返回值有函数名) 6 def timer(func): 7 def deco(*args, **kwargs): 8 start_time = time.time() 9 func(*args, **kwargs)#run test1 10 stop_time = time.time() 11 print("the func run time is %s" % (stop_time - start_time)) 12 return deco 13 @timer #test1 = timer(test1)#调用装饰器 14 def test1(): 15 time.sleep(3) 16 print("in the test1") 17 test1()#这个不是上面这个test1函数,其实是运行deco这个内存地址
5.装饰器实例升级版
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author:qinjiaxi 4 import time 5 user, password = 'qinjiaxi', 'abc123' 6 def auth(auth_type): 7 print("auth func", auth_type) 8 def out_wrapper(func): 9 def wrapper(*args, **kwargs): 10 print("wrapper func args", *args, **kwargs) 11 if auth_type == "local": 12 username = input("Username:").strip() 13 passwd = input("Password:").strip() 14 if user == username and password == password: 15 print("