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)函数参数写好。
分享到:
相关推荐
本文研究的主要是python实现Decorator模式,具体介绍如下。 一般来说,装饰器是一个函数,接受一个函数(或者类)作为参数,返回值也是也是一个函数(或者类)。首先来看一个简单的例子: # -*- coding: utf-8 -*- ...
demo python使用装饰器(Decorator)的方式实现单例模式 functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择
本文实例讲述了Python使用logging结合decorator模式实现优化日志输出的方法。分享给大家供大家参考,具体如下: python内置的loging模块非常简便易用, 很适合程序运行日志的输出。 而结合python的装饰器模式,则可...
使用python实现设计模式中的单例模式。单例模式是一种比较常用的设计模式,其实现和使用场景判定都是相对容易的。本文将简要介绍一下python中实现单例模式的几种常见方式和原理。一方面可以加深对python的理解,另一...
一、装饰器decorator ... 比较常用的功能一般使用decorator来实现,例如python自带的staticmethod和classmethod。 装饰器有两种形式: 复制代码 代码如下: @A def foo(): pass 相当于: 复制代码 代码如下
在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远不止于此,Python提供了一个语法和一个编程特性来加强这方面的功能。Python提供的语法就是装饰...
4、装饰模式【Decorator】 5、桥接模式【Bridge】 6、组合模式【Composite】 7、享元模式【Flyweight】 三、行为型模式 1、模板方法模式【Template Method】 2、观察者模式【Observer】 3、状态模式【State】 4、...
本文就介绍以decorator来实现 singleton 模式的方法。示例代码如下: ##----------------------- code begin ----------------------- # -*- coding: utf-8 -*- def singleton(cls): """Define a c
1:Python如何实现单例模式? Python有两种方式可以实现单例模式,下面两个例子使用了不同的方式实现单例模式:... 使用decorator来实现单例模式 def singleton(cls): instances = {} def getinstance(): if cls not in
在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远不止于此,Python提供了一个语法和一个编程特性来加强这方面的功能。 首先需要了解一下Python中...
pageFactory的设计模式能在java里执行的原因是java自带了PageFactory类,而在python中没有这样的包,但是已经有人写好了pageFactory在python的包,可以拿来用 pageFactory 用于python支持的py文件 __all__ = ['...
代码都可以直接运行,部分设计模式有多种实现,主要的设计模式如下:Creational-abstract_factory,Creational-factory_method,Creational-simple_factory,Creational-singleton,Creational-builder,Creational-...
在 Python 中,我们可以用多种方法来实现单例模式: 使用模块 使用 __new__ 使用装饰器(decorator) 使用元类(metaclass) 概念 简单说,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,...
本文实例讲述了Python实现对一个函数应用多个装饰器的方法。分享给大家供大家参考,具体如下: 下面的例子展示了对一个函数应用多个装饰器,可以加多个断点,在debug模式下,查看程序的运行轨迹。。。 #!/usr/bin/...
学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了! 这里就简单讨论下python的几种装饰模式: 一 无参装饰器: # 装饰器 import time # 装饰器,记录函数运行时间 def ...
最近新需求来了,要给系统增加几个资源权限。... 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 In PythonDesign Patterns Introduction(设计模式介绍)Strategy Pattern(策略模式)实现:design_patterns/strategy.py示例:examples/strategy_example.pyObserver ...
OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持 OOP 的 decorator 外,直接从语法层次支持 decorator。 如果你熟悉 python 的话,对它一定不会陌生。那么我们先来看一下 python 里的装饰器是什么样子的...