首先要明白裝飾器是用來給函數(shù)增加額外功能的烹俗。
常用的工具函數(shù)
import time
from functools import wraps
import inspect
import sys
import logging
def timeit(func):
"""統(tǒng)計函數(shù)運行時間"""
t0 = time.perf_counter()
func()
return time.perf_counter() - t0
def count(func):
"""統(tǒng)計遞歸函數(shù)執(zhí)行次數(shù)"""
# @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):
"""跟蹤函數(shù),便于查看過程。"""
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
帶參數(shù)的裝飾器
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
統(tǒng)計調(diào)用次數(shù) 增加緩存 增加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)
非常好的實現(xiàn)
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