`
luozhaoyu
  • 浏览: 343157 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

python实现decorator模式

阅读更多
python有个很常用的语法糖是@decorator,使用它可以很方便的创建decorator装饰器模式。(当然,@的用处可不只用在创建装饰器模式)方法有两种,一种是通过创建一个包裹类Wrapper,另一种就是直接通过一个函数创建closure

简要说下装饰器模式:不改变目标的内部行为,改变目标的外在表现方式的一种模式。重点在于,它一定不干涉“内政”,只可以在目标的外围进行修饰,对目标是透明的。

函数的方法最简单
def wrap(num):
    print("wrap initialed")
    def w(func):
        print("w start", num)
        def w2(*args):
            print("w2 start")
            func(*args)
            print("w2 end")
            return "some thing"       
        return w2
    return w

@wrap(10)
def foo2(num, string):
    print(string * num)

print("BEING:")
foo2(3, 'z')
foo2(4, 'y')
print(foo2)

输出结果是:
wrap initialed
('w start', 10)
BEING:
w2 start
zzz
w2 end
w2 start
yyyy
w2 end
<function w2 at 0x7f25d74735f0>

这里就相当与执行了语句
wrap(10)(foo2)(3, 'z')

每一层都先计算出本层的对象,然后再调用被嵌套的函数
这里可以看到
wrap initialed
('w start', 10)

最先输出了一次,说明虽然是包裹函数,但是其已经形成了闭包,全局唯一

如果使用类来实现,情况也比较类似
import datetime
class Wrapper(object):
    def __init__(self, num = -1):
        print("Wrapper Initialed", num)
        self.num = num
        
        
    def __call__(self, func):
        print("Wrapper Called")
        # 以下表明参数的写法虽运行无误,但是是没有意义的
        def w(fff, ggg, *args):
            print("Wrapper Preparing", datetime.datetime.now())
            # 这样传参数是没有意义的
            func(num = ggg, x = self.num,  *args)
            print("Wrapper Finished", datetime.datetime.now())
#        w.__name__ = func.__name__
        return w

#将值3传入Wrapper的self.num
@Wrapper(3)
def foo(num = 1, x = 'z', *args):
    print(x * num, args, 'x=', x, 'num=', num)

    
if __name__ == '__main__':
    print('BEGIN:')
    foo(2, 'a')
    foo(3, 'b')
    print(foo)

输出结果是:
('Wrapper Initialed', 3)
Wrapper Called
BEGIN:
('Wrapper Preparing', datetime.datetime(2012, 5, 5, 0, 25, 58, 136713))
('aaa', (), 'x=', 3, 'num=', 'a')
('Wrapper Finished', datetime.datetime(2012, 5, 5, 0, 25, 58, 136829))
('Wrapper Preparing', datetime.datetime(2012, 5, 5, 0, 25, 58, 136864))
('bbb', (), 'x=', 3, 'num=', 'b')
('Wrapper Finished', datetime.datetime(2012, 5, 5, 0, 25, 58, 136920))
<function w at 0x7f11d4f21758>

可以看出Wrapper类也只执行了一次初始化。我怀疑可不可能是因为
foo = Wrapper(3)(foo)(*args)
返回了一个闭包。通过最后一行的打印结果证实了我的想法。这个类也形成了一个闭包。

值得注意的有两点:一是Wrapper类使用了__call__函数,这个函数仅在发生调用时instance(*args),才会被激活,相当与instance.__call__(*args)
二是不要瞎折腾。 我在这里尝试把Wrapper的参数,传递给foo,这里需要w函数和foo的参数列表保持一致就可以不报错。但是这样做起不到改变foo函数行为的作用,顶多改变这个foo函数的默认参数,所以是毫无意义的!如果没有特殊必要,请不要把Wrapper的参数往foo中塞,Wrapper的函数仅在foo调用前后调用才有意义。

最后一点写参数表的心得体会是,在写装饰器的时候,如果拿不准func参数怎么写,怎么把它包装起来,那么就先写func(*args),然后再完善上面一层封包,直至最后把w(func)函数参数写好。
0
0
分享到:
评论

相关推荐

    python实现Decorator模式实例代码

    本文研究的主要是python实现Decorator模式,具体介绍如下。 一般来说,装饰器是一个函数,接受一个函数(或者类)作为参数,返回值也是也是一个函数(或者类)。首先来看一个简单的例子: # -*- coding: utf-8 -*- ...

    python使用装饰器(Decorator)的方式实现单例模式

    demo python使用装饰器(Decorator)的方式实现单例模式 functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择

    Python使用logging结合decorator模式实现优化日志输出的方法

    本文实例讲述了Python使用logging结合decorator模式实现优化日志输出的方法。分享给大家供大家参考,具体如下: python内置的loging模块非常简便易用, 很适合程序运行日志的输出。 而结合python的装饰器模式,则可...

    Python实现Singleton模式的方式详解

    使用python实现设计模式中的单例模式。单例模式是一种比较常用的设计模式,其实现和使用场景判定都是相对容易的。本文将简要介绍一下python中实现单例模式的几种常见方式和原理。一方面可以加深对python的理解,另一...

    python装饰器decorator介绍

    一、装饰器decorator ... 比较常用的功能一般使用decorator来实现,例如python自带的staticmethod和classmethod。 装饰器有两种形式: 复制代码 代码如下: @A def foo():  pass 相当于: 复制代码 代码如下

    分析Python中设计模式之Decorator装饰器模式的要点

    在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远不止于此,Python提供了一个语法和一个编程特性来加强这方面的功能。Python提供的语法就是装饰...

    python实现常用的23种设计模式:含源代码、详细文档说明

    4、装饰模式【Decorator】 5、桥接模式【Bridge】 6、组合模式【Composite】 7、享元模式【Flyweight】 三、行为型模式 1、模板方法模式【Template Method】 2、观察者模式【Observer】 3、状态模式【State】 4、...

    Python下singleton模式的实现方法

    本文就介绍以decorator来实现 singleton 模式的方法。示例代码如下: ##----------------------- code begin ----------------------- # -*- coding: utf-8 -*- def singleton(cls): """Define a c

    Python经典面试题.doc

    1:Python如何实现单例模式? Python有两种方式可以实现单例模式,下面两个例子使用了不同的方式实现单例模式:... 使用decorator来实现单例模式 def singleton(cls): instances = {} def getinstance(): if cls not in

    Python装饰器模式定义与用法分析

    在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远不止于此,Python提供了一个语法和一个编程特性来加强这方面的功能。 首先需要了解一下Python中...

    PageFactory设计模式基于python实现

    pageFactory的设计模式能在java里执行的原因是java自带了PageFactory类,而在python中没有这样的包,但是已经有人写好了pageFactory在python的包,可以拿来用 pageFactory 用于python支持的py文件 __all__ = ['...

    精心整理的23种python设计模式代码

    代码都可以直接运行,部分设计模式有多种实现,主要的设计模式如下:Creational-abstract_factory,Creational-factory_method,Creational-simple_factory,Creational-singleton,Creational-builder,Creational-...

    python单例模式的多种实现方法

    在 Python 中,我们可以用多种方法来实现单例模式: 使用模块 使用 __new__ 使用装饰器(decorator) 使用元类(metaclass) 概念 简单说,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,...

    Python实现对一个函数应用多个装饰器的方法示例

    本文实例讲述了Python实现对一个函数应用多个装饰器的方法。分享给大家供大家参考,具体如下: 下面的例子展示了对一个函数应用多个装饰器,可以加多个断点,在debug模式下,查看程序的运行轨迹。。。 #!/usr/bin/...

    python装饰器三种装饰模式的简单分析

    学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了! 这里就简单讨论下python的几种装饰模式: 一 无参装饰器: # 装饰器 import time # 装饰器,记录函数运行时间 def ...

    Python装饰器实现几类验证功能做法实例

    最近新需求来了,要给系统增加几个资源权限。... def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): if not current_user.can(permission): abort(403) return f(*args,

    design_patterns

    design_patterns(设计模式)Design Patterns In PythonDesign Patterns Introduction(设计模式介绍)Strategy Pattern(策略模式)实现:design_patterns/strategy.py示例:examples/strategy_example.pyObserver ...

    JS装饰器函数用法总结

    OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持 OOP 的 decorator 外,直接从语法层次支持 decorator。 如果你熟悉 python 的话,对它一定不会陌生。那么我们先来看一下 python 里的装饰器是什么样子的...

Global site tag (gtag.js) - Google Analytics