python中的装饰器(decorator)一般采用语法糖的形式,是一种语法格式。比如:@classmethod,@staticmethod,@property,@xxx.setter,@wraps(),@func_name等都是python中的装饰器。
装饰器,装饰的对象是函数或者类。各种装饰器的作用都是一样的:改变被装饰函数或者方法的功能,性质。
一,装饰器的官方定义
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
简单使用:def 函数名(func):def 内部函数名():func() #执行函数 return 内部函数名
不带参数函数的装饰器(不推荐)
import time
def outter(func):
def inner():
print('内部方法开始执行')
time_start = time.time()
func()
time_end = time.time()
print("一共花费了{0}秒时间".format(t_end - t_start, ))
return inner
@outter
def test1():
time.sleep(5)
print('执行sleep函数')
if __name__ == '__main__':
test1()
上面一个实例是简单的装饰器,执行顺序是先执行func()上面的代码,再执行func()里面的代码,最后再执行func()下方的代码,但是我们经常会碰到内部函数传参的情况,上面这种方法就不适用了,这个时候我们可以适用*args和**kwargs做下兼容,如下:
带参函数的装饰器
import time
def outter(func):
def inner(*args,**kwargs):
print('内部方法开始执行')
time_start = time.time()
func()
time_end = time.time()
print("一共花费了{0}秒时间".format(t_end - t_start, ))
return inner
@outter
def test1(count):
time.sleep(count)
print('执行sleep函数')
if __name__ == '__main__':
test1(2)
装饰器带参数
import time
def repeat(nums):
def how_much_time(func):
def inner(*args,**kwargs):
print('内部方法开始执行')
t_start = time.time()
for i in range(nums):
func(*args,**kwargs)
t_end = time.time()
print("一共花费了{0}秒时间".format(t_end - t_start, ))
return inner
return how_much_time
@repeat(nums=2)
def sleep5(count):
time.sleep(count)
print('内部函数开始执行')
if __name__ == '__main__':
sleep5(1)
装饰器和类使用(注意inner函数一定要加上self,并且在返回func的地方也要加上self)
import time
def deco(func):
def inner(self,*args,**kwargs):
print('zhixing')
return func(self)
return inner
class A:
@deco
def hobby(self):
print('111')
if __name__ == '__main__':
A().hobby()
装饰类(注意:inner里面不用加self,并且返回的func后面需要加()
def deco(func):
def inner(*args,**kwargs):
print('zhixing')
return func()
return inner
@deco
class A:
def hobby(self):
print('111')
if __name__ == '__main__':
A().hobby()