Python装饰器 December 1, 2017 / 2 min read dev , python 长期寻找好的装饰器 1. Log (1) 传统函数 from functools import wrapsimport time def logit(filename='out.log'): def logging_decorator(func): @wraps(func) def wrapped_func(*args, **kwargs): t = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) log_string = func.__name__ + " was called on " + t print(log_string) with open(filename, 'a') as f: f.write(log_string + '\n') return func(*args, **kwargs) return wrapped_func return logging_decorator @logit()def my_func1(): pass @logit('shit.log')def my_func2(): pass my_func1()my_func2() (2) 使用类 class Cls_logit(object): _filename = 'cls_logit.log' def __init__(self, func): self.func = func def __call__(self, *args): t = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) log_string = self.func.__name__ + " called on " + t print(log_string) with open(self._filename, 'a') as f: f.write(log_string + '\n') self.notify() return self.func(*args) def notify(self): pass Cls_logit._filename = 'cls_logit2.log' @Cls_logitdef my_func3(arg1): print('in my_func3 with', arg1) my_func3(3) 2. Auth验证 from functools import wraps def requires_auth(f): @wraps(f) def decorated(*args, **kwargs): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): authenticate() return f(*args, **kwargs) return decorated @requires_authdef user_some_action(): pass 3. 递归内存优化 from functools import wraps def memoize(function): print('wizardry here') memo = {} @wraps(function) def wrapper(*args): if args in memo: return memo[args] else: rv = function(*args) memo[args] = rv return rv return wrapper @memoizedef fibonacci(n): if n < 2: return n return fibonacci(n - 1) + fibonacci(n - 2) # fibonacci(25) 执行上面代码,虽然注释掉了fibonacci(25)(也就是没调用函数),但还是会打印wizardry here这行代码,可见装饰器的魔法就在于直接在函数定义后立马替换原来函数。 未完待续