python: 设计模式(design pattern)之修饰器模式(decorator)
来源:互联网 发布:苹果激活策略查询软件 编辑:程序博客网 时间:2024/05/17 01:12
修饰器模式是面向对象编程领域的一种设计模式。 通过向一个类对象动态的添加新的行为而实现。 修饰器可以给某个对象添加一些功能, 而不是整个类添加功能, 所以很灵活。
在python中, 我们可以使用decorators对callable的objects(注意包括functions, methods, 或者类classes)进行一些简单的修饰, 使得这些objects具有一些新的行为。
要理解decorators, 我们必须首先知道, python中, functions也是一个对象, 就想string, variables, class , integers等一样。 函数是根据给定的参数吐出产生的值的。
我们可以将一个函数作为一个参数传递给另一个函数, 也可以将一个函数赋值给一个变量, 或者函数返回一个函数。
如下, 返回一个函数:
def foobar(original_function): # make a new function def new_function(): # some code return new_function
decorator的定义:
一个decorator就是一个function, 吃callable object作为其参数, 然后将添加修饰后的callable obeject(例如函数)作为一个value返回去。
如下例就是对类进行修饰。例如, 下面就是一个修饰器:
def verbose(original_function): # make a new function that prints a message when original_function starts and finishes def new_function(*args, **kwargs): print("Entering", original_function.__name__) original_function(*args, **kwargs) print("Exiting ", original_function.__name__) return new_function
要使用decorator也很简单。
我们可以将一个函数传进去, 得到新一个新的修饰后的函数talkative_widget_func。 如下:
def widget_func(): # some code talkative_widget_func = verbose(widget_func)
def widget_func(): # some code widget_func = verbose(widget_func)注意上述返回的函数命名为widget_func, 和传进去的原始函数一样。
除此之外, python还有一个decortation syntax。 也就是使用“@”去创建decoration lines. 这个feature就是语法糖(syntax sugar), 是的我们可以将上面的例子重新写为如下形式:
@verbosedef widget_func(): # some code
上述产生的结果和上面的增强版本一样了。 这样我们的新的widget_func函数就具有原始的widget_func所有的行为在加上varbose修饰器添加的行为了。
不光可以修饰函数, 也可以对类进行修饰。程序如下:
#!/usr/bin/python#decotor design patternimport sysYELLOW = '\033[93m'RED = '\033[91m'NORMAL = '\033[0m'class Person(object): def __init__(self, name, age): # constructor self.name = name self.age = age def __str__(self): return '%s is %s' %(self.name, self.age)# decorator class to wrapps an object passed in#for age < 20, print NOEMAL#for 20 < age < 20, print YELLOW#for age > 30, print REDclass PersonDecorator(Person): def __init__(self, person): self._person = person def __getattr__(self, name): return getattr(self._person, name) def __str__(self): age = self._person.age colour = NORMAL if age >= 30: colour = RED elif age >= 20: colour = YELLOW return '%s%s%s' %(colour, self._person.__str__(), NORMAL)def main(): p = [] # list of person p.append(Person('Micheal', 25)) p.append(Person('Kate', 2)) p.append(Person('Mark', 48)) p.append(Person('Matt', 21)) for person in p: if '-c' in sys.argv: person = PersonDecorator(person) print person if __name__ == '__main__': main()运行结果如下:
附录: 解释(stackoverflow摘录)
*args and **kwargs
Similarly, **kwargs
allows you to handle named arguments that you have not defined in advance:
如下:
>>> def table_things(**kwargs):... for name, value in kwargs.items():... print '{0} = {1}'.format(name, value)...>>> table_things(apple = 'fruit', cabbage = 'vegetable')cabbage = vegetableapple = fruit
You can also use both in the same function definition but *args
must occur before **kwargs
.http://www.wklken.me/posts/2013/12/21/how-to-use-args-and-kwargs-in-python.html
解释如下:在函数中使用*和**是用于传递可变长参数, *args用于传递非命名剪枝可变长参数列表。 **kwargs用作传递键值可变长参数列表。 如下, 传递一个位置参数和两个可变长参数。
def test_var_args(farg, *args): print "formal arg:", farg for arg in args: print "another arg:", argtest_var_args(1, "two", 3)
def test_var_kwargs(farg, **kwargs): print "formal arg:", farg for key in kwargs: print "another keyword arg: %s: %s" % (key, kwargs[key])test_var_kwargs(farg=1, myarg2="two", myarg3=3)
运行结果如下:
上述语法也可以出现在调用函数中, 如下:
def test_var_args_call(arg1, arg2, arg3): print "arg1:", arg1 print "arg2:", arg2 print "arg3:", arg3args = ("two", 3)test_var_args_call(1, *args)如下:
或者:
def test_var_args_call(arg1, arg2, arg3): print "arg1:", arg1 print "arg2:", arg2 print "arg3:", arg3kwargs = {"arg3": 3, "arg2": "two"} #ie dictionarytest_var_args_call(1, **kwargs)
- python: 设计模式(design pattern)之修饰器模式(decorator)
- 设计模式之 -- Decorator pattern (修饰模式)
- 装饰设计模式(decorator design pattern)
- 设计模式2--装饰模式(the decorator design pattern)
- 设计模式之二(decorator pattern)
- 7.5.1.2 装饰设计模式(THE DECORATOR DESIGN PATTERN)
- 设计模式笔记之装饰者模式(Decorator Pattern)
- C#设计模式之装饰者模式(Decorator Pattern)
- 设计模式总结之Decorator Pattern(装饰者模式)
- Design Pattern: Decorator 模式
- 设计模式-装饰模式(Decorator Pattern)
- 设计模式之Decorator Pattern
- Java设计模式 Design Pattern:包装模式 Decorator Pattern
- 设计模式(三)The Decorator Pattern 装饰器模式
- 设计模式 —— 装饰器模式(Decorator Pattern)
- 【设计模式】装饰器模式(Decorator Pattern)
- 设计模式(Design Pattern)
- 设计模式(Design Pattern)
- 数据挖掘、C#与Matlab混合编程链接
- Java的运行原理
- ZigBee小系统的运行原理
- PHP把mysql中数据类型为bit的数据转换成int
- 启动Tomcat6.x时,manager does not exist or is not a readable directory-解决
- python: 设计模式(design pattern)之修饰器模式(decorator)
- Can't find right android-platform for project 解决方案
- 第五周项目1-体验常成员函数
- 【SDOI2015Round1】游记Day2
- .NET学习之数据库总结
- 第五周项目2-对象作为数据成员
- 开发实例 PM2.5实时监测
- [leetcode]Convert Sorted List to Binary Search Tree
- exit()和_exit()的区别