装饰器背后的主要动机源自python面向对象编程,装饰器是在函数调用之上的修饰,这些修饰仅是当声明一个函数或者方法的时候,才会应的额外调用.
装饰器语法定义
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
pass
装饰器语法产生背景
装饰器是在引入类方法和静态方法时,为了定义静态方法出现的.比如把staticFunc()定义为静态方法
不使用装饰器
class MyClass(object):
def staticFunc():
pass
staticFunc = staticmethod(staticFunc)
使用装饰器:
class MyClass(object):
@staticmethod
def staticFunc():
pass
装饰器可以如函数调用一样"堆叠"起来.
@deco2
@deco1
def func(arg1, arg2, ....):
pass
其实就等同于下面的组合函数
def func(arg1, arg2, ...):
pass
func = deco2(deco1(func))
对某个方法比如func应用了装饰方法后,func就重新指向了deco2(deco1(func)) 返回的函数对象.
所以装饰器会接受一函数对象参数,并返回一个函数对象, 装饰器内部都会插上自己的处理代码(比如打印日志,实现计时等),并执行传入的函数对象调用.
有参数和无参数的装饰器
无参数的
@deco
def foo():
pass
等同于 foo = deco(foo)
有参数的
@decomaker(deco_args)
def foo():
pass
等同于 foo = decomaker(deco_args)(
例 1 无参数装饰器
>>> def decorator(func):
print ('decorator...') #1 被装饰函数定义时调用一次
def deco_func():
print ('deco_func...') #2 每次被装饰函数调用时,都会调用
return func() #3 执行被装饰函数
return deco_func
>>> @decorator
def func():
print ('hello...')
decorator... #代码#1输出,只在func定义时输出一次
>>> func()
deco_func... #代码#2,装饰器插入的代码
hello... #代码3,执行被装饰函数
例 2 装饰器有参数
>>> def decoWithArgs(decoArg):
print ('decoWithArgs...', decoArg)
def decoReal(func):
print ('decoReal...')
def deco_func():
print ('deco_func...', decoArg)
return func()
return deco_func
return decoReal
>>> @decoWithArgs('deco 1')
def func1():
print ('func1...')
decoWithArgs... deco 1
decoReal...
>>> @decoWithArgs('deco 2')
def func2():
print ('func2...')
decoWithArgs... deco 2
decoReal...
>>> func1()
deco_func... deco 1
func1...
>>> func2()
deco_func... deco 2
func2...
例 3 装饰器和被装饰函数都有参数
>>> def decoWithArgs2(decoArg):
print ('decoWithArgs...', decoArg)
def decoReal(func):
print ('decoReal...')
def deco_func(arg1, arg2):
print ('deco_func...', decoArg)
return func(arg1, arg2)
return deco_func
return decoReal
>>> @decoWithArgs2('function with args')
def func(arg1, arg2):
print ('func...', arg1, arg2)
decoWithArgs... function with args
decoReal...
>>> func('abce', 1234)
deco_func... function with args
func... abce 1234