• 为了保证你在浏览本网站时有着更好的体验,建议使用类似Chrome、Firefox之类的浏览器~~
    • 如果你喜欢本站的内容何不Ctrl+D收藏一下呢,与大家一起分享各种编程知识~
    • 本网站研究机器学习、计算机视觉、模式识别~当然不局限于此,生命在于折腾,何不年轻时多折腾一下

python设计模式–装饰器模式

Python admin 2周前 (08-05) 59次浏览 0个评论 扫描二维码

感觉这个不像是设计模式,在 python 的语法糖中包含了一种叫装饰器的东西,正好与设计模式的这个玩意名字也是相同的,其实你读了这篇文章也会发现这两个说的也是同一个东西,没什么区别。

装饰器如果记得不太清楚的话可以看我这篇文章,相信你应该可以看得懂python 装饰器探究

套用之前装饰器的一篇文章中介绍装饰器部分时,装饰器主要解决的是一些公共部分的代码复用的问题,当然也可以在不修改原始函数代码的基础上增加新的功能比如 log 日志。

先看一下原始计算斐波那契算法

 def fibonacci(n):
       assert(n >= 0), 'n must be >= 0'
       return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)
   if __name__ == '__main__':
       from timeit import Timer
       t = Timer('fibonacci(8)', 'from __main__ import fibonacci')
       print(t.timeit())

上面这个代码耗时是这个样子的

在每次计算 f(4)的时候都要去计算 f(3)一直到 f(0)这个中间消耗了大量的时间,因此这种原始的算法会带来很大的时间消耗,所以需要优化。

优化的思路就是储存中间计算变量,这样下次需要访问中间变量的时候直接取数据就好了,常见的操作就是使用字典去保存这些中间变量,字典的访问时间复杂度是 O(1)高效

下面看一个优化不同数学函数计算的代码,主要在优化数据存储与读取的方式

# coding: utf-8

import functools


def memoize(fn):
    known = dict()

    @functools.wraps(fn)
    def memoizer(*args):
        if args not in known:
            known[args] = fn(*args)
        return known[args]

    return memoizer


@memoize
def nsum(n):
    '''返回前 n 个数字的和'''
    assert(n >= 0), 'n must be >= 0'
    return 0 if n == 0 else n + nsum(n-1)


@memoize
def fibonacci(n):
    '''返回斐波那契数列的第 n 个数'''
    assert(n >= 0), 'n must be >= 0'
    return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)

if __name__ == '__main__':
    from timeit import Timer
    measure = [{'exec': 'fibonacci(100)', 'import': 'fibonacci',
                'func': fibonacci}, {'exec': 'nsum(200)', 'import': 'nsum',
                                     'func': nsum}]
    for m in measure:
        t = Timer('{}'.format(m['exec']), 'from __main__ import \
            {}'.format(m['import']))
        print('name: {}, doc: {}, executing: {}, time: \
            {}'.format(m['func'].__name__, m['func'].__doc__,
                       m['exec'], t.timeit()))

总结

就是使用装饰器模式可以很好的拓展你的软件的新的功能,在不修改原来代码的基础上。从软件的角度来看,Django 和 Grok 都适用装饰器来实现不同的目的,比如控制 HTTP 压缩和缓存。装饰器模式是实现关注切面的一个很好的解决方案,因为它们通用,而且并不很适合 OOP 范式。我们在使用案例小节提到了很多的关注切面的种类。实际上,在实现小节演示了一个关注切面的例子:记忆器。我们见到了装饰器如何帮助我们保证代码的整洁,而不用付出性能上的代价。


Deeplearn, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明python 设计模式–装饰器模式
喜欢 (0)
admin
关于作者:

您必须 登录 才能发表评论!