装饰器
1. 装饰器的一步步实现
## 装饰器:装饰器定义一个函数,该函数是用来为其他函数添加额外的工能
## 装饰器就是不修改源代码以及调用方式的基础上增加新功能
## 开放封闭原则
# 开放:指的是对拓展工能是开放的
# 封闭: 指的是对修改源代码是封闭的
## 添加一个计算代码运行时间的工能(修改了源代码)
import time
def index(name,age):
start = time.time()
time.sleep(3)
print('我叫%s,今年%s岁'%(name,age))
end = time.time()
print(end - start)
index(age = 18,name = 'yanchen')
# --------------------------------------------------------------------------
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def wrapper():
start = time.time()
index1(name="yanchen", age=18)
time.sleep(3)
end = time.time()
print(end - start)
wrapper()
# 解决了修改原函数,但是也改变了函数调用方式
# --------------------------------------------------------------------------------------
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def wrapper(name,age):
start = time.time()
index1(name, age)
time.sleep(3)
end = time.time()
print(end - start)
wrapper('yanchen',18)
# -----------------------------------------------------------------------------------
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def wrapper(*args,**kwargs):
start = time.time()
index1(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
wrapper('yanchen',age = 18)
# ------------------------------------------------------------------------------------
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def outer():
func = index
def wrapper(*args,**kwargs):
start = time.time()
fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return wrapper
f = outer() # f本质就是wrapper函数
### 继续改进
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def outer(fun):
def wrapper(*args,**kwargs):
start = time.time()
fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return wrapper
f = outer(index1) # f本质就是wrapper函数
f(name='yanchen',age=18)
# 继续改进,偷梁换柱
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
def outer(fun):
def wrapper(*args,**kwargs):
start = time.time()
fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return wrapper
index1 = outer(index1) # f本质就是wrapper函数
index1(name='yanchen',age=18) # 新功能加上了,也没有修改函数的调用方式
# ---------------------------------------------------------
2. 装饰器最终版本
# 被装饰函数有返回值
########### 装饰器最终版本
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
return [name,age] # 有返回值
def outer(fun):
def wrapper(*args,**kwargs):
start = time.time()
arg = fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return arg # 返回index1 的返回值
return wrapper
index1 = outer(index1) # f本质就是wrapper函数
res = index1(name='yanchen',age=18) # 新功能加上了,也没有修改函数的调用方式,把原函数的返回值也拿到了
# --------------------------------------------------------------------------------------------------
3. 装饰器语法糖
def outer(fun):
def wrapper(*args,**kwargs):
start = time.time()
arg = fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return arg # 返回index1 的返回值
return wrapper
@outer
def index1(name,age):
print('我叫%s,今年%s岁' % (name, age))
return [name,age] # 有返回值
# -----------------------------------------------
# 与原函数伪装的更像一点
from functools import wraps # 用于把原函数的属性特征赋值给另一个函数
def outer(fun):
@wraps(fun) # 可以把fun函数的所有属性特征加到wrapper函数身上
def wrapper(*args,**kwargs):
# wrapper.__name__ = fun.__name__
# wrapper.__doc__ = fun.__doc__
# 手动赋值麻烦
start = time.time()
arg = fun(*args,**kwargs)
time.sleep(3)
end = time.time()
print(end - start)
return arg # 返回index1 的返回值
return wrapper
@outer
def index1(name,age):
'''我是index1''' # 通过help(index)函数来查看 文档信息,可以通过index.__doc__ = 'xxxxx' 来给某个函数赋值文档信息
# 通过 index__name__ 可以获得函数的名字,也可以对其进行赋值
print('我叫%s,今年%s岁' % (name, age))
return [name,age] # 有返回值
4. 有参装饰器
4.1 不用语法糖
### 不用语法糖
def auth(func,db_type):
def wrapper(*args,**kwargs):
name = input('your name:').strip()
pwd = input('your password:').strip()
if db_type == 'file':
print('基于文件验证')
if name == 'yanchen' and pwd == 'yc123':
print('login success')
res = func(*args,**kwargs)
return res
else:
print('用户名或者密码错误!!')
elif db_type == 'mysql':
print('基于mysql验证')
elif db_type == 'ldap':
print('基于ldap验证')
else:
print('基于其他途径验证')
return wrapper
def index(x,y):
print('index->>%s:%s'%(x,y))
index = auth(index,'file')
index('yanchen',18)
4.4.2 语法糖01
#---------------------------------------------------------------------
# 语法糖01
def auth(db_type = "file"):
def deco(func):
def wrapper(*args,**kwargs):
name = input('your name:').strip()
pwd = input('your password:').strip()
if db_type == 'file':
print('基于文件验证')
if name == 'yanchen' and pwd == 'yc123':
print('login success')
res = func(*args,**kwargs)
return res
else:
print('用户名或者密码错误!!')
elif db_type == 'mysql':
print('基于mysql验证')
elif db_type == 'ldap':
print('基于ldap验证')
else:
print('基于其他途径验证')
return wrapper
return deco
deco = auth(db_type = 'file')
@deco
def index(x,y):
print('index->>%s:%s'%(x,y))
index('yanchen',18)
deco = auth(db_type = 'mysql')
@deco
def index(x,y):
print('index->>%s:%s'%(x,y))
index('yanchen',18)
4.3 标准语法糖
# ---------------------------------------------------------------------------------
# 标准语法糖模板
def auth(外界传递的参数):
def deco(func):
def wrapper(*args,**kwargs):
'''自己扩展的功能'''
res = func(*args,**kwargs)
return res
return wrapper
return deco
@auth(外界传递的参数)
def index(x,y):
print(x,y)
return(x,y)
# 标准语法糖02(例子)
def auth(db_type = "file"):
def deco(func):
def wrapper(*args,**kwargs):
name = input('your name:').strip()
pwd = input('your password:').strip()
if db_type == 'file':
print('基于文件验证')
if name == 'yanchen' and pwd == 'yc123':
print('login success')
res = func(*args,**kwargs)
return res
else:
print('用户名或者密码错误!!')
elif db_type == 'mysql':
print('基于mysql验证')
elif db_type == 'ldap':
print('基于ldap验证')
else:
print('基于其他途径验证')
return wrapper
return deco
@auth(db_type = 'file')
def index(x,y):
print('index->>%s:%s'%(x,y))
index('yanchen',18)
@auth(db_type = 'file')
def index(x,y):
print('index->>%s:%s'%(x,y))
index('yanchen',18)
No Comments