装饰器的作用
扩展函数的功能,即:将函数入参给装饰器函数,装饰器函数里扩展了函数功能后,将新函数返回。
软件的设计应该遵循:扩展开放,修改封闭 原则
写法
@装饰器名字,写在被装饰对象正上方
核心思想:
函数可以入参,函数也是对象
1、最简单的装饰器
def a_new_decorator(a_func): # 定义一个装饰器
def wrapTheFunction():
print("装饰器中的第一次打印")
a_func()
print("装饰器中的第二次打印")
return wrapTheFunction
@a_new_decorator # 此处装饰了test函数,后续直接调用test函数,是已经被扩展后的结果了
def test():
print('test')
test() #输出是被装饰后的效果了
输出
装饰器中的第一次打印
test
装饰器中的第二次打印
2、被装饰函数有返回值,被装饰函数需要入参
改进1:当被装饰的函数有返回值的时候
改进2:当被装饰的函数有入参的时候
import time
def time_sleep(func):
def inner_func(*args,**kwargs):
time_begin = time.time()
res = func(*args,**kwargs)
time_end = time.time()
print(f'当前耗时{time_end - time_begin}')
return res
return inner_func
@time_sleep # 相当于执行了 origi_func = time_sleep(origi_func)
def origi_func(in_arg):
print('begin')
time.sleep(1)
print('end')
print(in_arg)
return '返回值'
res = origi_func('传入的参数')
print(res)
输出
begin
end
传入的参数
当前耗时1.0094623565673828
返回值
3、装饰器需要入参 \ 修改属性
1、装饰器需要入参,需要在最外面再包一层函数来传入装饰器参数
2、装饰器默认会重写函数名字和注释文档,要想不被重写需要调用functools库里的raps语法改被装饰函数的属性
from functools import wraps
def auth(driver):
def wrapper(func):
@wraps(func) #此处保证被装饰后,func的说明文档没变,作用类似18行
def inner_func(*args, **kwargs):
print(f'当前鉴权驱动为{driver}')
name = input('请输入用户名-->')
pass_word = input('请输入密码-->')
if name == 'zhaowenhui' and pass_word == 'wenzi':
res = func(*args, **kwargs)
else:
print('用户名或者账号错误')
res = None
return res
return inner_func
# wrapper.__name__ = func.__name__ # 改属性,类似于这个语句
return wrapper
@auth(driver = 'file') # 装饰器入参
def func(name, pass_word):
print(f'当前账号为{name}, 密码为{pass_word}')
return name
res = func('zhaowenhui','wenzi')
print(f'函数名{func.__name__}')
输出
当前鉴权驱动为file
请输入用户名-->zhaowenhui
请输入密码-->wenzi
当前账号为zhaowenhui, 密码为wenzi
函数名func