装饰器本质上是一个Python函数(返回值是一个函数对象),它可以让其他函数在不需要任何代码变动的前提下增加额外功能。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
第一种:不带参数的函数装饰器 写一个最普通的装饰器,这种装饰器是不能传参的,只能对被装饰函数,执行固定逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def logger (func ): def wrapper (*args, **kw ): print ('我准备开始执行:{}函数了' .format (func.__name__)) func(*args, **kw) print ('函数执行完啦' ) return wrapper @logger def add (x, y ): print ('{} + {} = {}' .format (x, y, x+y)) add(200 , 50 )
第二种:带参数的函数装饰器 写一个能传参的装饰器,可以根据不同的场景进行调整。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import timedef logger (tt ): def wrapper1 (func ): def wrapper2 (*args, **kw ): print ('我在{}时刻开始执行:{}函数了' .format (tt, func.__name__)) func(*args, **kw) print ('在{}时刻函数执行完啦' .format (time.time())) return wrapper2 return wrapper1 @logger(time.time( ) ) def add (x, y ): print ('{} + {} = {}' .format (x, y, x+y)) add(200 , 50 )
第三种:不带参数的类装饰器 基于类的装饰器,必须实现init和call两个内置函数,前者用于接收被装饰函数,后者用于实现装饰逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 class logger (object ): def __init__ (self, func ): self.func = func def __call__ (self, *args, **kwargs ): print ('[INFO]: the function {func}() is running...' .format (func=self.func.__name__)) return self.func(*args, **kwargs) @logger def add (x, y ): print ('{} + {} = {}' .format (x, y, x+y)) add(200 , 50 )
第四种:带参数的类装饰器 带参数的类装饰器和不带参数的类装饰器有很大不同,init不再接收被装饰函数而是接收传入参数,call既接收被装饰函数又要实现装饰逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class logger (object ): def __init__ (self, level='INFO' ): self.level = level def __call__ (self, func ): def wrapper (*args, **kwargs ): print ('[{level}]: the function {func}() is running...' .format (level=self.level, func=func.__name__)) func(*args, **kwargs) return wrapper @logger(level='WARNING' ) def add (x, y ): print ('{} + {} = {}' .format (x, y, x+y)) add(200 , 50 )