一.什么是装饰器
- python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
二.装饰器的使用
2.1原始函数
import time
def index():
time.sleep(3)
print('welcome to index page')
return 10
start_time=time.time()
index()
stop_time=time.time()
print('run time is {}'.format(stop_time-start_time))
# 问题:上述代码虽然能事现功能,但是如果多个函数需要使用,就必须在每个函数前后加入代码
2.2.装饰器版本(无参数)
import time
def index():
time.sleep(3)
print('welcome to index page')
return 10
def timer(func):
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print('run time is {}'.format(stop_time - start_time))
return wrapper
index=timer(index) # timer(index)返回wrapper,wrapper=index
index() # index()等于执行wrapper()
# 这里timer就是装饰器函数
2.3.有参数装饰器
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res=func(*args,**kwargs)
#func(*args, **kwargs)
stop_time = time.time()
print('run time is {}'.format(stop_time - start_time))
print(res)
return res
return wrapper
def home(name):
time.sleep(1)
print('hello world',name)
home=timer(home)
home('weixu')
2.4.最终版(语法@)
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res=func(*args,**kwargs)
stop_time = time.time()
print('run time is {}'.format(stop_time - start_time))
return res
return wrapper
@timer
def xixi():
time.sleep(2)
print('fuck you')
xixi()
三.获取函数原始信息
3.1.去常规函数名
def func():
print('running')
print(func.__name__)
func()
3.2.取被装饰函数名
def wrapper(func):
def inner():
print('beginning')
result=func()
print('ending')
return result
return inner
@wrapper
def func():
print('running')
print(func.__name__)
func()
# 通过执行结果发现,取出来函数名是inner,但是我们想取的是func。
# 解决方法1
def wrapper(func):
def inner():
print('beginning')
result=func()
print('ending')
return result
inner.__doc__=func.__doc__
inner.__name__=func.__name__
return inner
@wrapper
def func():
print('running')
print(func.__name__)
func()
# 方法2
用functools模块下提供一个装饰器wraps
from functools import wraps
def warpper(func):
@wraps(func)
def inner():
result=func()
return result
return inner
@warpper
def func():
print(func.__name__)
func()
四.多个装饰器装饰统一个函数
def wrapper1(func):
def inner():
print('wrapper1 before')
func()
print('wrapper1 ending')
return inner
def wrapper2(func):
def inner():
print('wrapper2 before')
func()
print('wrapper2 ending')
return inner
@wrapper1
@wrapper2
def f():
print('f')
f()
# 执行结果
wrapper1 before
wrapper2 before
f
wrapper2 ending
wrapper1 ending
代码执行过程:
1.f=wrapper2(f)=inner
2.inner=warpper1(inner)=warpper1.inner
3.执行warpper1下的innner,先打印wrapper1 before,然后执行func,这里的func就是warpper2中的inner