1、什么是装饰器
python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
这个函数有两个特别之处:
- 参数是一个函数;
- 返回值是一个函数;
2、为什么要使用装饰器
一个简单的例子:
def run():
print('run')
run()
要求:在执行这个函数之前先输出一个’hello world’。
我们可以这样输出:
def run():
print('hello world')
print('run')
run()
如果在添加一个函数同样我们要求在输出这个函数之前输出’hello world’
def run():
print('hello world')
print('run')
run()
def add(a,b):
c = a + b
print('hello world')
print('结果是:%s'%c)
add(1,2)
我们可以这样在执行输出之前再添加,试想一下如果我有一百个函数都需要执行这样的需求呢,一个一个添加过于繁琐,修改也不方便,这个时候就用到了装饰器。
3、装饰器用法
(1)装饰器使用是通过@符号的,放在函数的上面;
(2)装饰器中定义的函数,要使用*args,**kwargs两对兄弟组合,并且在这个函数执行原始函数的时候也要把*args,**kwargs
传进去;
(3)*args,**kwargs
可以表示任何参数(*args表示位置参数、kwargs表示关键字参数),在定义不同函数的时候,传递的参数可能不同,所以利用*args,**kwargs
我们表示任何参数;
(4)需要使用functools.wraps在装饰器中的函数上把传进来的这个函数进行一个包裹,这样就不会丢失原来函数的__name__属性。
# @my_log
def run():
print('run')
# run = my_log(run) = wrapper
print('-'*10)
print(run.__name__)
run()
01.注释掉装饰器函数,我们可以看到输出的是’run’这个函数的名称。
02.不注释掉装饰器输出的是装饰器函数返回的内容
03.使用functools.wraps在装饰器中的函数上把传进来的这个函数进行一个包裹,这样打印出来的还是原来函数的__name__属性。
from functools import wraps
# 装饰器实际上就是一个函数
#有两个特别之处
# 1.参数是一个函数
# 2.返回值是一个函数
# 在所有的函数之前,都要打印一个hello world
def my_log(func):
@wraps(func)
def wrapper(*args,**kwargs): #*args,**kwargs表示任何参数-------#args表示位置参数、kwargs表示关键字参数
print('hello world')
func(*args,**kwargs)
return wrapper
@my_log
def run():
print('run')
# run = my_log(run) = wrapper
print('-'*10)
print('__name__是:'run.__,name__) # run.__name__代表的是run这个函数名称
print('-'*10)
run()
@my_log
def add(a,b):
c = a + b
print('结果是:%s'%c)
print('-'*10)
print('__name__是:'add.__,name__)
print('-'*10)
add(1,2)