装饰器
装饰器
一、概念
装饰器作用是为了给某一函数在不改变该函数代码的情况下增加额外的功能,实现原理是通过闭包实现,改进后可以通过语法糖实现,具体有函数装饰器,类装饰器等可以传参。
二、原理
1.1 闭包装饰器
1 def debug(func): 2 def wrapper(): 3 print "[DEBUG]: enter {}()".format(func.__name__) 4 return func() 5 return wrapper 6 7 def say_hello(): 8 print "hello!" 9 10 say_hello = debug(say_hello) # say_hello函数添加功能,并保持say_hello函数名不变
2.1 语法糖装饰器
1 def debug(func): 2 def wrapper(): 3 print "[DEBUG]: enter {}()".format(func.__name__) 4 return func() 5 return wrapper 6 7 @debug 8 def say_hello(): 9 print "hello!"
三、被装饰函数传参
如果被装饰的函数需要传入参数,那么这个装饰器就坏了。因为返回的函数并不能接受参数,你可以指定装饰器函数wrapper
接受和原函数一样的参数,比如:
1 def debug(func): 2 def wrapper(something): # 指定一毛一样的参数 3 print "[DEBUG]: enter {}()".format(func.__name__) 4 return func(something) 5 return wrapper # 返回包装过函数 6 7 @debug 8 def say(something): 9 print "hello {}!".format(something)
四、带参数的装饰器
1 def deco(arg): 2 def _deco(func): 3 def __deco(): 4 print("before %s called [%s]." % (func.__name__, arg)) 5 func() 6 print("after %s called [%s]." % (func.__name__, arg)) 7 8 return __deco 9 10 return _deco 11 12 13 @deco("mymodule") 14 def myfunc(): 15 print(" myfunc() called.") 16 17 18 @deco("module2") 19 def myfunc2(): 20 print(" myfunc2() called.") 21 22 23 myfunc() 24 myfunc2() 25 """ 26 before myfunc called [mymodule]. 27 myfunc() called. 28 after myfunc called [mymodule]. 29 before myfunc2 called [module2]. 30 myfunc2() called. 31 after myfunc2 called [module2]. 32 """
五、基于类装饰器
六、内置装饰器
1.1 @property
1.2 @staticmethod
1.3 @classmethod
七、装饰器顺序