什么是函数修饰符?函数修饰符就是对原有函数做一层包装。
修饰符的使用步骤:
1)首先定义修饰符函数;
2)然后@修饰符;
3)在紧跟修饰符的下一行定义要使用修饰符的函数。
示例1:
def deco(func): def _deco(): print("before myfunc() called.") func() print("after myfunc() called.") return _deco def myfunc1(): print 'myfunc1' deco(myfunc1)() print '------------------' @deco def myfunc2(): print 'myfunc2' myfunc2()
运行结果:
before myfunc() called.
myfunc1
after myfunc() called.
------------------
before myfunc() called.
myfunc2
after myfunc() called.
使用@符号定义修饰符时,其实就是将其下的被修饰函数作为参数传递给修饰符函数,并立即执行一次修饰符函数。
@deco
def func1:
----- 等价于 ------
func1 = deco( func1 )
示例2:
def deco(func): def _deco(*args, **kwargs): print("before myfunc() called.") func(*args, **kwargs) print("after myfunc() called.") return _deco @deco def myfunc(a, b): print a + b myfunc(1, 2)
运行结果:
before myfunc() called.
3
after myfunc() called.
被修饰的函数有参数时,在修饰函数里,使用可变参数*args和**kwargs,这样会把所有接收来的参数,原样不动的再转给原函数,是惯用法。
示例3:
def deco(*args): def _deco(func): def __deco(): print("before %s called %s." % (func.__name__, args)) func() print("after %s called %s." % (func.__name__, args)) return __deco return _deco def myfunc1(): print 'myfunc1' deco('sunchp')(myfunc1)() print '------------------' @deco('sunchp') def myfunc2(): print 'myfunc2' myfunc2()
运行结果:
before myfunc1 called ('sunchp',).
myfunc1
after myfunc1 called ('sunchp',).
------------------
before myfunc2 called ('sunchp',).
myfunc2
after myfunc2 called ('sunchp',).
让装饰器带参数,跟示例1比,在外层多了一层包装。
@deco('XXX')
def func1:
----- 等价于 ------
func1 = deco('XXX')( func1 )
示例4:
def deco1(func): def _deco(): print("deco1 before myfunc() called.") func() print("deco1 after myfunc() called.") return _deco def deco2(func): def _deco(): print("deco2 before myfunc() called.") func() print("deco2 after myfunc() called.") return _deco def myfunc1(): print 'myfunc1' deco1(deco2(myfunc1))() print '------------------' @deco1 @deco2 def myfunc2(): print 'myfunc2' myfunc2()
运行结果:
deco1 before myfunc() called.
deco2 before myfunc() called.
myfunc1
deco2 after myfunc() called.
deco1 after myfunc() called.
------------------
deco1 before myfunc() called.
deco2 before myfunc() called.
myfunc2
deco2 after myfunc() called.
deco1 after myfunc() called.
注意多个装饰器的执行顺序,应该是先执行下面的,然后是上面的。这里应先执行deco2,然后是deco1。