python函数装饰器用法实例详解

1144次阅读  |  发布于5年以前

本文实例讲述了python函数装饰器用法。分享给大家供大家参考。具体如下:

装饰器经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。


    #! coding=utf-8 
    import time 
    def timeit(func): 
      def wrapper(a): 
        start = time.clock() 
        func(1,2) 
        end =time.clock() 
        print 'used:', end - start 
        print a 
      return wrapper 
    @timeit
    # foo = timeit(foo)完全等价, 
    # 使用之后,foo函数就变了,相当于是wrapper了 
    def foo(a,b): 
      pass 
    #不带参数的装饰器 
    # wraper 将fn进行装饰,return wraper ,返回的wraper 就是装饰之后的fn 
    def test(func): 
      def wraper(): 
        print "test start" 
        func() 
        print "end start" 
      return wraper 
    @test 
    def foo(): 
      print "in foo" 
    foo() 

输出:


    test start 
    in foo 
    end start 

装饰器修饰带参数的函数:


    def parameter_test(func): 
      def wraper(a): 
        print "test start" 
        func(a) 
        print "end start" 
      return wraper 
    @parameter_test 
    def parameter_foo(a): 
      print "parameter_foo:"+a 
    #parameter_foo('hello') 

输出:


    >>> 
    test start 
    parameter_foo:hello 
    end start 

装饰器修饰不确定参数个数的函数:


    def much_test(func): 
      def wraper(*args, **kwargs): 
        print "test start" 
        func(*args, **kwargs) 
        print "end start" 
      return wraper 
    @much_test 
    def much1(a): 
      print a 
    @much_test 
    def much2(a,b,c,d ): 
      print a,b,c,d 
    much1('a') 
    much2(1,2,3,4) 

输出:


    test start 
    a 
    end start 
    test start 
    1 2 3 4 
    end start 

带参数的装饰器,再包一层就可以了:


    def tp(name,age): 
      def much_test(func): 
        print 'in much_test' 
        def wraper(*args, **kwargs): 
          print "test start" 
          print str(name),'at:'+str(age) 
          func(*args, **kwargs) 
          print "end start" 
        return wraper 
      return much_test 
    @tp('one','10') 
    def tpTest(parameter): 
      print parameter 
    tpTest('python....') 

输出:


    in much_test 
    test start 
    one at:10 
    python.... 
    end start 


    class locker: 
      def __init__(self): 
        print("locker.__init__() should be not called.") 
      @staticmethod 
      def acquire(): 
        print("locker.acquire() called.(这是静态方法)") 
      @staticmethod 
      def release(): 
        print("locker.release() called.(不需要对象实例") 
    def deco(cls): 
      '''cls 必须实现acquire和release静态方法''' 
      def _deco(func): 
        def __deco(): 
          print("before %s called [%s]." % (func.__name__, cls)) 
          cls.acquire() 
          try: 
            return func() 
          finally: 
            cls.release() 
        return __deco 
      return _deco 
    @deco(locker) 
    def myfunc(): 
      print(" myfunc() called.") 
    myfunc() 

输出:


    >>> 
    before myfunc called [__main__.locker].
    locker.acquire() called.(这是静态方法)
     myfunc() called.
    locker.release() called.(不需要对象实例
    >>> 


    class mylocker: 
      def __init__(self): 
        print("mylocker.__init__() called.") 
      @staticmethod 
      def acquire(): 
        print("mylocker.acquire() called.") 
      @staticmethod 
      def unlock(): 
        print(" mylocker.unlock() called.") 
    class lockerex(mylocker): 
      @staticmethod 
      def acquire(): 
        print("lockerex.acquire() called.") 
      @staticmethod 
      def unlock(): 
        print(" lockerex.unlock() called.") 
    def lockhelper(cls): 
      '''cls 必须实现acquire和release静态方法''' 
      def _deco(func): 
        def __deco(*args, **kwargs): 
          print("before %s called." % func.__name__) 
          cls.acquire() 
          try: 
            return func(*args, **kwargs) 
          finally: 
            cls.unlock() 
        return __deco 
      return _deco 
    class example: 
      @lockhelper(mylocker) 
      def myfunc(self): 
        print(" myfunc() called.") 
      @lockhelper(mylocker) 
      @lockhelper(lockerex) 
      def myfunc2(self, a, b): 
        print(" myfunc2() called.") 
        return a + b 
    if __name__=="__main__": 
      a = example() 
      a.myfunc() 
      print(a.myfunc()) 
      print(a.myfunc2(1, 2)) 
      print(a.myfunc2(3, 4))

输出:


    before myfunc called.
    mylocker.acquire() called.
     myfunc() called.
     mylocker.unlock() called.
    before myfunc called.
    mylocker.acquire() called.
     myfunc() called.
     mylocker.unlock() called.
    None
    before __deco called.
    mylocker.acquire() called.
    before myfunc2 called.
    lockerex.acquire() called.
     myfunc2() called.
     lockerex.unlock() called.
     mylocker.unlock() called.
    3
    before __deco called.
    mylocker.acquire() called.
    before myfunc2 called.
    lockerex.acquire() called.
     myfunc2() called.
     lockerex.unlock() called.
     mylocker.unlock() called.
    7

希望本文所述对大家的Python程序设计有所帮助。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8