装饰器

2015-12-02  本文已影响43人  00cadc01cbc1

最近在看廖雪峰老师的关于装饰器的教程, 写的非常好,链接: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

上一篇下一篇

猜你喜欢

热点阅读