装饰器,装饰器的语法糖,有参装饰器
装饰器
1、什么是装饰器
装饰器是一个用来为被装饰者添加功能的工具
被装饰者:函数
装饰器:可以用函数实现装饰器这种工具
2、为何要用装饰器
为了在不修改被装饰器对象源代码以及调用方式的前提下
为被装饰对象添加上新功能
3、如何用装饰器
函数装饰器模板一
def outter(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
例子
# 被装饰对象
# import time
#
# def index(x):
# print('welcome to index page %s' % x)
# time.sleep(3)
#
# index(111)
# 方案五:把wrapper伪装的跟被装饰对象一样
# import time
#
#
# def index(x):
# print('welcome to index page %s' % x)
# time.sleep(3)
# return 7777
#
#
# def outter(func): # func = 地址1
# def wrapper(*args, **kwargs):
# start = time.time()
# res = func(*args, **kwargs)
# stop = time.time()
# print(stop - start)
# return res
# return wrapper
#
#
# index = outter(index) # index = outter(地址1) # index -> 地址2
#
# res = index(111) # res = wrapper(111)
# print(res)
# 方案六:把wrapper伪装的跟被装饰对象一样,更进一步
import time
def index(x):
"""
这是index的帮助信息
"""
print('welcome to index page %s' % x)
time.sleep(3)
return 7777
def outter(func): # func = 地址1
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
stop = time.time()
print(stop - start)
return res
wrapper.__doc__ = index.__doc__
wrapper.__name__ = index.__name__
return wrapper
index = outter(index) # index = outter(地址1) # index -> 地址2
# help(index)
装饰器的语法糖
在调用之后的函数头加 @outter ,相当于outter(index的内存地址)
import time
from functools import wraps
def outter(func): # func = 地址1
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
stop = time.time()
print(stop - start)
return res
return wrapper
@outter # index = outter(index的内存地址)
def index(x):
"""
这是index的帮助信息
"""
print('welcome to index page %s' % x)
time.sleep(3)
return 7777
res = index(225)
print(res)
叠加多个装饰器
import time
def deco1(func1): # func1 = wrapper2的内存地址
def wrapper1(*args, **kwargs):
start = time.time()
res1 = func1(*args, **kwargs)
print(time.time() - start)
return res1
return wrapper1
def deco2(func2): # func2 = wrapper3的内存地址
def wrapper2(*args, **kwargs):
inp_user = input('username>>>: ').strip()
inp_pwd = input('password>>>: ').strip()
if inp_user == 'egon' and inp_pwd == '123':
print("登录成功")
res2 = func2(*args, **kwargs)
return res2
else:
print("登录失败")
return wrapper2
@deco2 deco2(index的内存地址)-->wrapper2的内存地址
@deco1 deco1(wrapper2的内存地址) -> wrapper1的内存地址
def index():
print('index功能')
time.sleep(1)
index()
有参装饰器
运行 1 才会运行函数体内部
语法糖可直接 outter(engine = 'file')
def outter(engine = 'file'):
def deco2(func2):
def wrapper2(*args, **kwargs):
1 if engine == 'file':
inp_user = input('username>>>: ').strip()
inp_pwd = input('password>>>: ').strip()
if inp_user == 'egon' and inp_pwd == '123':
print("登录成功")
res2 = func2(*args, **kwargs)
return res2
else:
print("登录失败")
elif engine == "mysql":
print("基于mysql的认证")
elif engine == "ldap":
print("基于ladp的认证")
return wrapper2
return deco2
@outter(engine='ldap') # @deco2 # index=deco2(index) # index=wrapper2
def index():
print('index功能')
# index = deco2(index,engine='mysql')
index() # wrapper()
# 结论:
# def outter(x,y):
# def deco(func):
# def wrapper(*args,**kwargs):
# print(x,y)
# res = func(*args,**kwargs)
# return res
# return wrapper
# return deco
#
#
# @outter(111,22)
# def index():
# print('index')
#
# index()

浙公网安备 33010602011771号