装饰器

作者: 00cadc01cbc1 | 来源:发表于2015-12-02 15:46 被阅读43次

    最近在看廖雪峰老师的关于装饰器的教程, 写的非常好,链接:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000#0

    1. 函数是可作为变量传递的。
    import datetime
    def now():
      print datetime.datetime.now()
    
    f = now()
    f()
    >>> 2016-05-05 17:03:47.370000
    
    2. 不带参数的装饰器

    @functools.wrap()函数把原始函数的name等属性复制到wrapper()函数中,
    否则,有些依赖函数签名的代码执行就会出错

    #定义装饰器
    import datetime
    import functools
    
    
    def log(func):
      @functools.wrap(func)
      def wrapper(*args, **kwrags):
        print 'call %s' % func.__name__
        return func(*args, **kwrags)
    return wrapper
    
    @log
    def now():
      print datetime.datetime.now()
    >>> call now()
    >>> 2016-05-05 17:03:47.370000
    
    3 带参数的装饰器
    def log(text):
      def decorator(func):
        @functools.wrap(func)
        def wrapper(*args, **kwrags):
          print '%s %s' %s(text, func.__name__)
          return func(*args, **kwrags)
        return wrapper
      return decorator
    
    @log('Hangzhou')
    def now():
      print datetime.datetime,now()
    >>> Hangzhou now
    >>> 2016-05-05 17:03:47.370000
    

    4. 练习实现一个能在函数调用的前后打印出'begin call'和'end call'的日志。

    def call_print(func):
      @functools.wrap(func)
      def wrapper(*args, **kwrags):
        print '%s begin call' % func.__name__
        res = func(*args, **kwrags)
        print '%s end call' % func.__name__
        return res
      return wrapper
    
    @call_print
    def now():
      print datetime.datetime.now()
     
      >>>  now begin call
      >>> 2016-05-05 17:03:47.370000
      >>> now end call
    
    5 编写一个即支持带参数的修饰器 又支持不带参数的修饰器
    def call_print(text):
      if callable(text):
        @functools.wrap(func)
        def wrapper(*args, **kwrags):
          print '%s begin call' % func.__name__
          res = func(*args, **kwrags)
          print '%s end call' % func.__name__
          return res
        return wrapper
      else:
        def decorator(func):
          @functools.wrap(func)
          def wrapper(*args, *kwrags):
            print '%s begin call' % func.__name__
            res = func(*args, **kwrags)
            print '%s end call' % func.__name__
            return res
          return wrapper
        return decorator
    
    @log
     def now():
        print datetime.datetime.now()
    @log('Hangzhou')
     def now():
        print datetime.datetime.now()
    
    >>> now begin call
    >>>2016-05-05 17:03:47.370000
    >>> now end call
    
    >>> Hangzhou begin call 
    >>> 2016-05-05 17:03:47.370000
    >>> Hangzhou end call 
    

    **************

    #装饰器带参数,并且包装函数带参数
    def deco(arg):
      def _deco(func):
        def __deco(*args, **kwargs):
            print('befor %s called [%s].' % (func.__name__, arg))
            ret = func(*args, **kwargs)
            print('after %s called [%s].' % (func.__name__, arg))
            return ret
        return __deco
      return _deco
    @deco('mymodule')
    def myfunc(a, b):
    print('myfunc() called.')
    return a+b
    print myfunc(10, 199)
    

    参考
    http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

    相关文章

      网友评论

          本文标题:装饰器

          本文链接:https://www.haomeiwen.com/subject/vktshttx.html