python 装饰器最佳实践

www.yunxcloud.cn

首先要明白装饰器是用来给函数增加额外功能的。

常用的工具函数

import time
from functools import wraps
import inspect
import sys
import logging

def timeit(func):
"""统计函数运行时间"""
t0 = time.perf_counter()
func()
return time.perf_counter() - t0

def count(func):
"""统计递归函数执行次数"""
# @wraps(func)
def counted(args):
counted.call_count += 1
return func(
args)
counted.call_count = 0
return counted

def memorize(f):
"""缓存"""
cache = {}
@wraps(f)
def memorized(args):
if args not in cache:
cache[args] = f(
args)
return cache[args]
return memorized

def trace(func):
"""跟踪函数,便于查看过程。"""
def afunc(args):
print("call", func.name, "with", args)
v = func(
args)
print(func.name, "return ",v)
return v
return afunc

def main(fn):
"""@main ---> name == "main" """
if inspect.stack()[1][0].f_locals['name'] == 'main':
args = sys.argv[1:] # Discard the script name from command line
fn(*args) # Call the main function
return fn

带参数的装饰器

def logged(level, name=None, message=None):
def decorate(func):
logname = name if name else func.module
log = logging.getLogger(logname)
@wraps(func)
def wrapper(*args, *kwargs):
logmsg = "{}--call --{}".format(func.name, args)
log.log(level, logmsg)
return func(
args, **kwargs)
return wrapper
return decorate

统计调用次数 增加缓存 增加debug 功能。

@logged(logging.DEBUG)
@count
@memorize
def fib(x):
return x if x < 2 else fib(x-1) + fib(x-2)

print(fib(10), fib.dict)

非常好的实现

flask 和 bottle 中的路由绑定

将add_url_rule 进行了一层包装,能够很简洁的使用装饰器的语法来绑定路由

def route(self, rule, **options):
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator

@route('/')
def example():
pass

flask login 中的判断是否登录了。。

要注意的地方。 装饰器本质上是一个高阶的函数,用来将函数包裹起来。

注意装饰器使用的顺序。

还有就是使用了装饰器的话原函数的一些信息可能会丢掉。需要通过一个方法

来将原函数的一些东西来绑定到新的上面。

博客 https://www.97up.cn/

更多例子

https://wiki.python.org/moin/PythonDecoratorLibrary

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,...
    chen_000阅读 5,142评论 0 3
  • 基础1.r''表示''内部的字符串默认不转义2.'''...'''表示多行内容3. 布尔值:True、False(...
    neo已经被使用阅读 5,697评论 0 5
  • 神将不可能变为可能。 11月3号下午去医院例行产检,又要等几个小时。我们坐在椅子上,老公玩斗地主,我逛淘宝准备宝宝...
    暖暖末阅读 1,332评论 0 0
  • 园子觉察到男友的反常,约会次数明显减少、电话也变少了,她开始感觉到,不详的脚步声正渐渐接近自己。但她故意不闻不问。...
    粒粒往前冲阅读 4,781评论 0 0
  • 刚刚考完研的我成绩并不理想,我不想再来一年,也不想去反省问题出在哪里,我害怕最终得出我脑子不好使这种可怕的结...
    吾猫不吃鱼阅读 3,550评论 0 0