装饰器-decorator

def memo
  cache = {}
  @wraps(func)
  def wrapper(*args):
      if args not in cache:
        cache[args] = func(*args)
      return cache[args]
  return wrapper
  1. 我们定义如下函数,将输入参数乘2并返回
def f(x):
'''
double input
'''
   return x * 2
>>> f(3), f('a')
>>> 9, 'aa'
  1. 如果我们要求输入参数x必须为int型,否则返回None,可以通过定义函数fn_int来实现
def fn_int(func):
    def wrapper(*args):
        for arg in args:
            if not isintance(arg, int):
                return 
       return func(*args)
    return wrapper
>>> g = fn_int(f)
>>> f(3), f('a')
6, 'aa'
>>> g(3), g('a')
6, None
  1. 可以通过添加装饰器符号@来将上面两步骤合并
@fn_int
def f(x):
'''
double input
'''
  return x * 2
>>> f(3), f('a')
6, None

但这时会有如下的问题

>>> f.__name__, f.__doc__
wrapper, None

而我们预期的结果是

f
double input
  1. 上面的问题可以由functools.wraps来解决
from functools import wraps
def fn_int(func):
    @wraps(func)  ### important line
    def wrapper(*args):
        for arg in args:
            if not isintance(arg, int):
                return 
       return func(*args)
    return wrapper
@fn_int
def f(x):
'''
double input
'''
   return x * 2
>>> f(3), f('a')
6, None
>>> f.__name__, f.__doc__
f
double input

你可能感兴趣的:(装饰器-decorator)