• 技术文章 >后端开发 >Python教程

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

    2016-06-10 15:10:51原创614
    本文实例讲述了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程序设计有所帮助。

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:python 函数装饰器
    千万级数据并发解决方案

    相关文章推荐

    • 详细介绍python的numpy模块• Python多进程知识点总结• Python模块化整理和第三方模块的安装(总结分享)• 一起聊聊Python的编码样式• 带你搞懂Python反序列化
    1/1

    PHP中文网