欢迎各位兄弟 发布技术文章
这里的技术是共享的
  好了,现在我们来看一下各种decorator的例子:
这个例实在是太经典了,整个网上都用这个例子做decorator的经典范例,因为太经典了,所以,我这篇文章也不能免俗。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  | from functools import wrapsdef memo(fn):    cache = {}    miss = object()    @wraps(fn)    def wrapper(*args):        result = cache.get(args, miss)        if result is miss:            result = fn(*args)            cache[args] = result        return result    return wrapper@memodef fib(n):    if n < 2:        return n    return fib(n - 1) + fib(n - 2) | 
上 面这个例子中,是一个斐波拉契数例的递归算法。我们知道,这个递归是相当没有效率的,因为会重复调用。比如:我们要计算fib(5),于是其分解成 fib(4) + fib(3),而fib(4)分解成fib(3)+fib(2),fib(3)又分解成fib(2)+fib(1)…… 你可看到,基本上来说,fib(3), fib(2), fib(1)在整个递归过程中被调用了两次。
而我们用decorator,在调用函数前查询一下缓存,如果没有才调用了,有了就从缓存中返回值。一下子,这个递归从二叉树式的递归成了线性的递归。
这个例子没什么高深的,就是实用一些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  | import cProfile, pstats, StringIOdef profiler(func):    def wrapper(*args, **kwargs):        datafn = func.__name__ + ".profile" # Name the data file        prof = cProfile.Profile()        retval = prof.runcall(func, *args, **kwargs)        #prof.dump_stats(datafn)        s = StringIO.StringIO()        sortby = 'cumulative'        ps = pstats.Stats(prof, stream=s).sort_stats(sortby)        ps.print_stats()        print s.getvalue()        return retval    return wrapper | 
下面这个示例展示了通过URL的路由来调用相关注册的函数示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28  | class MyApp():    def __init__(self):        self.func_map = {}    def register(self, name):        def func_wrapper(func):            self.func_map[name] = func            return func        return func_wrapper    def call_method(self, name=None):        func = self.func_map.get(name, None)        if func is None:            raise Exception("No function registered against - " + str(name))        return func()app = MyApp()@app.register('/')def main_page_func():    return "This is the main page."@app.register('/next_page')def next_page_func():    return "This is the next page."print app.call_method('/')print app.call_method('/next_page') | 
注意:
1)上面这个示例中,用类的实例来做decorator。
2)decorator类中没有__call__(),但是wrapper返回了原函数。所以,原函数没有发生任何变化。