年轻人不要总熬夜

Python装饰器

Posted on By jax777


layout: post title: python装饰器 categories: python tag: python —

# 装饰器

## 简单装饰器

 def use_logging(func):
     def wrapper(*args, **kwargs):
         logging.warn("%s is running" % func.__name__)
         return func(*args, **kwargs)
     return wrapper

 def bar():
     print('i am bar')
 bar = use_logging(bar) bar()

@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作

 def use_logging(func):
    def wrapper(*args, **kwargs):
        logging.warn("%s is running" % func.__name__)
        return func(*args, **kwargs)
    return wrapper

 @use_logging
 def foo():
     print("i am foo")

 bar()

## 带参数的装饰器

 def use_logging(level):
     def decorator(func):
         def wrapper(*args, **kwargs): if level == "warn":
             logging.warn("%s is running" % func.__name__)
             return func(*args)

         return wrapper

     return decorator

         @use_logging(level="warn")
 def foo(name='foo'):
     print("i am %s" % name) foo()

## 类装饰器

相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器还可以依靠类内部的__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。

 class Foo(object):
     def __init__(self, func):
         self._func = func
     def __call__(self):
         print ('class decorator runing')
         self._func()
         print ('class decorator ending')
  @Foo
  def bar():
      print ('bar') bar()

# functools.wraps wraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器函数中,这使得装饰器函数也有和原函数一样的元信息了

 from functools import wraps
 def logged(func):
     @wraps(func)
     def with_logging(*args, **kwargs):
         print func.__name__ + " was called"
         return func(*args, **kwargs)
     return with_logging

     @logged
 def f(x):
     """does some math"""
     return x + x * x

     print f.__name__ # prints 'f'
 print f.__doc__ # prints 'does some math'