@Scrazy
2017-04-16T02:05:34.000000Z
字数 2880
阅读 1126
pythonPython中的装饰器真是个好东西。熟悉我的人都知道,挺能喷的一个人。但是,技术不是喷出来的,前言写的再花,也不会让我的装饰器比别人的更有威力。哈哈哈
装饰器是 Python 提供的一个语法糖,即:一个函数接受另一个函数作为参数并返回一个新的函数
func = decorate(func)
In [17]: from functools import wraps...:...: def log(func):...: @wraps(func)...: def wrapper(*args, **kw):...: print("I'm a log ^*^")...: result = func(*args, **kw)...: return result...: return wrapper...:In [19]: @log...: def hello():...: print('Hello World')...:In [20]: hello()I'm a log ^*^Hello World
请看
In [5]: from functools import wrapsIn [8]: def logs(file="info.log"):...: def decorate(func):...: @wraps(func)...: def wrapper(*args, **kw):...: log = func.__name__ + " was called"...: print(log)...: with open(file, 'a') as f:...: f.write(log + '\n')...: return wrapper...: return decorate...:In [11]: @logs()...: def hello():...: print('Hello World!')...:In [12]: hello()hello was calledIn [13]: @logs(file='info2.log')...: def hello2():...: print('Hello World!')...:In [14]: hello2()hello2 was called
from functools import wraps, partialimport loggingdef logged(func=None, *, level=logging.DEBUG, name=None, message=None):if func is None:return partial(logged, level=level, name=name, message=message)logname = name if name else func.__module__log = logging.getLogger(logname)logmsg = message if message else func.__name__@wraps(func)def wrapper(*args, **kwargs):log.log(level, logmsg)return func(*args, **kwargs)return wrapper# Example use@loggeddef add(x, y):return x + y@logged(level=logging.CRITICAL, name='example') # 高于 warning 级别的才会输出到屏幕def spam():print('Spam!')
就到这里吧,反正很少有人会来看。就一个人浪吧。
更新
In [1]: class Log():...: def __init__(self, file="info.log"):...: self.file = file...: def __call__(self, func):...: log = func.__name__ + " was called"...: print(log)...: with open(self.file, 'a') as f:...: f.write(log+'\n')...:In [2]: @Log()...: def hello():...: print('Hello World!')...:hello was called
可复制粘贴代码在这里
# coding: utf-8import functoolsdef cache(func):_cache = {}functools.wraps(func)def wrapper(*args):result = _cache.get(args)if not result:result = func(*args)_cache[args] = resultreturn resultreturn wrapper# testIn [5]: @cache...: def fib(n):...: if n < 2:...: return n...: return fib(n-1) + fib(n-2)...:In [6]: %time fib(200)CPU times: user 0 ns, sys: 0 ns, total: 0 nsWall time: 723 µsOut[6]: 280571172992510140037611932413038677189525In [7]: %time fib(200)CPU times: user 0 ns, sys: 0 ns, total: 0 nsWall time: 11.2 µs # 时间大幅减少Out[7]: 280571172992510140037611932413038677189525In [8]: %time fib(200)CPU times: user 0 ns, sys: 0 ns, total: 0 nsWall time: 13.4 µsOut[8]: 280571172992510140037611932413038677189525
flask_login.login_required 是也是一个装饰器,login_required 装饰器的主要作用就是让只有已登陆和认证过的用户才能继续调用被其装饰的视图(view)函数。下面是截取的 片段
def login_required(func):@wraps(func)def decorated_view(*args, **kwargs):if request.method in EXEMPT_METHODS:return func(*args, **kwargs)elif current_app.login_manager._login_disabled:return func(*args, **kwargs)elif not current_user.is_authenticated:return current_app.login_manager.unauthorized()return func(*args, **kwargs)return decorated_view
哦,对了,附上一个牛逼的链接,墙裂推荐不熟悉装饰器的小伙伴们看看。