1、定义:装饰器,就是把一个函数当作参数,返回一个替代版的函数
本质上就是一个返回函数的函数
2、作用:在不改变原函数的基础上给函数增加功能
3、装饰器
如:
def outer(func): ##()中是要装饰的函数,此函数名和任意,即参数
def inner(): ##定义的要装饰的内容的函数
print('*********') ##要装饰的内容
func() ##运行要装饰的函数
return inner() ##返回inner,就是返回装饰后的函数
@outer ##语法糖 (在不用改变原函数的情况下,修改函数的输出结果)
def shuchu():
print('wa ha ha')
@outer
def lizi():
print('hello world')
例子:
def outer(func):
def inner(age):
if age<0:
age = 0
else:
age= age
func(age)
return inner
@outer
def say(age):
print('name is %d years old' %(age))
say(10)
say(-10)
例子:
def desc(fun):
def add_info():
print('节日快乐')
fun()
print('下次来玩')
return add_info
@desc
def login():
print('login...')
login()
例子,装饰器实现函数计时器
import random
import string
import time ##导入计时器模块
import functools ##导入对装饰器装饰的模块
li = [random.choice(string.ascii_letters)for i in range(100)]
def timeit(fun): ##括号中即要装饰的函数参数,可随意,但在装饰器中必须统一
@functools.wraps(fun) ##对装饰器进行装饰,保留被装饰函数的函数名和帮助信息文档
def wapper(*args,**kwargs): ##args是指元组,kwarges是字典,因为输入的值不一定是那种类型
start_time = time.time() ##开始时间
res= fun(*args,**kwargs) ##执行函数,当被装饰的函数有返回值时,需要对返回值进行接收
end_time = time.time() ##结束时间
print('运行时间为: %.6f' %(end_time - start_time))
return res ##对接收的返回值进行返回
return wapper ##返回wapper函数,即装饰后的函数
@timeit
def con_add():
s =''
for i in li:
s+=(i+',')
print(s)
#con_add()
@timeit
def join_add():
print(','.join(li))
#join_add()
@timeit
def fun_list(n):
"""这是fun_list函数,被itemit装饰"""
return [2 * i for i in range(n)]
@timeit
def fun_map(n):
"""这是fun_map函数,被timeit装饰"""
return list(map(lambda x:x*2,range(n)))
print(fun_list.__name__) ##显示函数名
print(fun_list.__doc__) ##显示函数文档
print(fun_map.__name__)
print(fun_map.__doc__)
例子: 创建装饰器, 要求如下:
创建add_log装饰器, 被装饰的函数打印日志信息;
日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx
import time
import functools
#print(time.ctime()) ##显示字符串时间time.ctime()
def add_log(fun):
@functools.wraps(fun)
def wapper(*args, **kwargs):
start_time = time.time()
res = fun(*args, **kwargs)
end_time = time.time()
print('[%s] 函数名: %s 运行时间: %.6f 运行返回值结果: %s' % (time.ctime(), fun.__name__, end_time - start_time, res))
return res
return wapper
@add_log
def fun_list(n):
return [2 * i for i in range(n)]
fun_list(5)
4、多个装饰器时候,是自上到下执行的
def wang_a(fun):
def inner_a(*args,**kwargs):
print('A')
return fun(*args,**kwargs)
return inner_a
def wang_b(fun):
def inner_b(*args,**kwargs):
print('B')
return fun(*args,**kwargs)
return inner_b
@wang_b
@wang_a
def f(x):
print('wanghaha')
return x*2
f(1)
输出结果先B 后A
5、多个装饰器的应用场景:会采用多个装饰器先验证是否登陆成功,再验证权限是否足够
import functools
import inspect ##导入模块,可以生成一个字典
def is_admin(fun): ##判断权限
@functools.wraps(fun)
def wapper(*args,**kwargs):
inspect_res =inspect.getcallargs(fun,*args,**kwargs) ##inspect.getcallargs会返回一个字典,key值是形参value值是对应的实参
print(‘inspect的返回值是: %s’ %(inspect_res))
if inspect_res.get('name') == 'root':
temp = fun(*args,**kwargs)
return temp
else:
print('not root user,no permission add student')
return wapper
login_session = ['root','admin','redhat'] ##判断登陆
def is_login(fun):
@functools.wraps(fun)
def wapper(*args,**kwargs):
if args[0] in login_session:
temp = fun(*args,**kwargs)
return temp
else:
print('Error: %s未登陆' %(args[0]))
return wapper
@is_login
@is_admin
def add_student(name):
print('please input student information:')
add_student('root')
来源:CSDN
作者:dead_ls
链接:https://blog.csdn.net/Dead_LS/article/details/103457162