Python 函数装饰器探讨

来源:互联网 发布:jmeter 调用java 调试 编辑:程序博客网 时间:2024/04/29 18:14
装饰器背后的主要动机源自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 1decoReal...>>> @decoWithArgs('deco 2')    def func2():        print ('func2...')    decoWithArgs... deco 2decoReal...>>> func1()deco_func... deco 1func1...>>> func2()deco_func... deco 2func2...


例 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 argsdecoReal...>>> func('abce', 1234)deco_func... function with argsfunc... abce 1234