python—装饰器
1、装饰器
本质上函数,为其他函数添加附加功能
— 不修改被修饰函数的源代码
— 不修改被修饰函数的源代码调用方式
装饰器 = 高阶函数+函数嵌套+闭包
import time ### 定义装饰器 def timmer(func): def wrapper(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print('函数运行时间为:',(stop_time-start_time)) return res return wrapper @timmer def cal(l): res = 0 for i in l: res += i time.sleep(0.1) return res print(cal(range(5)))
2、高阶函数
函数的参数或返回值是函数名(函数名是内存地址)
### 高阶函数(函数参数是函数名),修改函数调用方式 import time def foo(): print('来来来啊俩') def test(func): print(func) start_time = time.time() func() stop_time = time.time() print('函数运行时间为:',(stop_time-start_time)) test(foo) ## 原来的调用方式 foo()
### 高阶函数(函数返回值是函数名) def foo(): print('from the foo') def test(func): return func foo = test(foo) foo()
import time def foo(): print('from the foo') ## 不修改foo源代码和调用方式 def timmer (func): start_time = time.time() func() stop_time = time.time() print('函数运行时间为:',(stop_time-start_time)) return func foo = timmer(foo) foo() ### 多运行了一次 foo()
3、函数嵌套
函数内定义另一个函数
def first(name): print('第一层 %s' %name) def second(): print('第二层') print(locals()) ## 两个局部变量 name和second() {'name': 'gogo', 'second': <function first.<locals>.second at 0x006A1150>} first('gogo')
def first(name): name = 'haha' print('第一层 %s' %name) def second(): name = 'kako' print('第二层%s' %name) second() first('gogo') ## 第一层 haha ## 第二层kako
4、装饰器框架
## 装饰器框架 : 高阶函数+函数嵌套 import time def timmer(func): def wrapper(): start_time = time.time() func() ### 执行rest() end_time = time.time() print('函数运行时间为:',(end_time-start_time)) return wrapper @timmer ## 相当于 test = timmer(test) def test(): time.sleep(0.1) print('test函数运行完毕') # test = timmer(test) ## 返回wrapper的地址 # test() ## 执行wrappper() test() ## test函数运行完毕 ##函数运行时间为: 0.10100579261779785
补充:
## 交换数值 a=1 b=2 a,b=b,a print(a,b)
5、装饰器例子
# 为函数加上认证功能 # 全局变量模拟session # 装饰器加参数 user_list = [ {'username':'Amy','passwd':'123'}, {'username':'Lisa', 'passwd': '123'}, {'username':'Lucy', 'passwd': '123'}, {'username':'Bob', 'passwd': '123'}, {'username':'Fly', 'passwd': '123'}, ] # 记录当前用户状态 current_dic = {'username':None,'login':False} def auth(auth_type='filedb'): ## 装饰器加参数 def auth_func(func): def wrapper(*args,**kwargs): if current_dic['username'] and current_dic['login']: res = func(*args, **kwargs) return res username = input('用户名:').strip() passwd = input('密码:').strip() for user_li in user_list: if username == user_li['username'] and passwd == user_li['passwd']: current_dic['username'] = username current_dic['login'] = True res = func(*args, **kwargs) return res else: print('用户名或密码错误!') return wrapper @auth(auth_type='filedb') ## auth_func=auth(auth_type='filedb') ---> @auth_func附加了auth_tupe参数 ---> index = auth_func(index) def index(): print('xx欢迎您!!') @auth(auth_type='filedb') def home(name): print('欢迎回到%s的主页!!' %name) index() home('abc')