1. 装饰器定义
1 2 3 4 5 6 7 8 9 10
| 装饰器由名称空间,函数对象,闭包函数组合而来
装饰:给被装饰对象添加额外的功能 器:指的是工具
装饰器的原则:开放封闭原则 开放:对扩展开放 封闭:对修改封闭 装饰器核心思想:在不改变被"装饰对象内部代码"和"原有调用方式"的基础上添加额外的功能
|
1 2 3 4 5 6 7 8 9
| eg: import time def index(): time.sleep(3) print('form index') start_time = time.time() index() end_time = time.time() print(end_time - start_time)
|
2. 装饰器简易版
给函数添加统计执行时间的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import time def run_time(func): def r_time(): start_time = time.time() func() end_time = time.time() print('程序运行时间为%s' % (end_time - start_time)) return r_time def for_loop(): for i in range(100000): pass def while_loop(): i = 0 while i < 100000: i += 1 for_loop = run_time(for_loop) for_loop() while_loop = run_time(while_loop) while_loop()
|
3. 装饰器参数问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import time def outer(func): def run_time(*args, **kwargs): start_time = time.time() func(*args, **kwargs) end_time = time.time() print("程序运行时间%s" % (end_time - start_time)) return run_time def get_name(name): time.sleep(1) print("from index name is %s" % name) def get_age(age): time.sleep(1) print("from func age is %s" % age)
get_name = outer(get_name) get_name('jason') get_age = outer(get_age) get_age(18)
|
4. 装饰器返回值问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def outer(func): def run_time(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("程序运行时间%s" % (end_time - start_time)) return res return run_time def num_max(a, b): time.sleep(1) if a > b: return a else: return b num_max = outer(num_max) print(num_max(11, 22))
|
5. 认证装饰器
小功能实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| def login(func): def auth(): username = input('username:').strip() passwd = input('passwd:').strip() if username == 'jason' and passwd == '123': func() else: print("认证失败") return auth def func1(): print("功能1") def func2(): print("功能2") func1 = login(func1) func1()
func2 = login(func2) func2()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| login_flag = {'flag': False}
def login(func): def auth(): if login_flag.get('flag'): func() else: username = input("username:").strip() passwd = input("passwd:").strip() if username == 'jason' and passwd == '123': func() login_flag['flag'] = True else: print("认证失败") return auth def func1(): print("功能1") def func2(): print("功能2")
func1 = login(func1) func1()
func2 = login(func2) func2()
|
6. 装饰器固定模板
1 2 3 4 5 6 7
| def outer(func): def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) print('执行函数之后可以添加的额外功能') return res return inner
|
7. 装饰器语法糖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| def outer(func): def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) print('执行函数之后可以添加的额外功能') return res return inner @outer def index(*args, **kwargs): print('from index') @outer def home(): print('from home') """ 装饰器语法糖书写规范 语法糖必须紧贴在被装饰对象的上方 装饰器语法糖内部原理 会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用 """
|
8. 装饰器双层语法糖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| login_flag = {'flag': False} def all_time(func): def run_time(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("程序执行时间%s" % (end_time - start_time)) return res return run_time def login(func): def auth(*args, **kwargs): if login_flag.get('flag'): res = func(*args, **kwargs) return res else: username = input("username:").strip() passwd = input("passwd:").strip() if username == 'jason' and passwd == '123': res = func(*args, **kwargs) login_flag['flag'] = True return res else: print("用户名或密码错误") return auth
@all_time @login def func1(name): print("功能1%s" % name) time.sleep(1) return '功能1->%s' % name
@all_time @login def func2(name): print("功能2%s" % name) time.sleep(1) return '功能2->%s' % name
print(func1('购物')) print(func2('付款'))
|
9. 装饰器三层语法糖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| def outter1(func1): print('加载了outter1') def wrapper1(*args, **kwargs): print('执行了wrapper1') res1 = func1(*args, **kwargs) return res1 return wrapper1
def outter2(func2): print('加载了outter2') def wrapper2(*args, **kwargs): print('执行了wrapper2') res2 = func2(*args, **kwargs) return res2 return wrapper2
def outter3(func3): print('加载了outter3') def wrapper3(*args, **kwargs): print('执行了wrapper3') res3 = func3(*args, **kwargs) return res3 return wrapper3
@outter1 @outter2 @outter3 def index(): print('from index')
|
10. 装饰器修复技术
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from functools import wraps def outer(func): @wraps(func) def inner(*args, **kwargs): print('执行函数之前可以添加的额外功能') res = func(*args, **kwargs) print('执行函数之后可以添加的额外功能') return res return inner
@outer def index(): print('from index') print(index) help(index)
def home(): """这是一个home函数""" print('from home')
|
11. 有参装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| def outer(source_data): def login_auth(func): def auth(*args,**kwargs): if source_data == 'file': print('file文件获取') elif source_data == 'MySQL': print('MySQL数据库获取') elif source_data == 'postgreSQL': print('postgreSQL数据库获取') else: print('用户名或密码错误 无法执行函数') return auth return login_auth
@outer('file') def index(): print('from index') @outer('MySQL') def home(): print('from home')
index() home()
|