装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
装饰器语法
(1)无参数装饰器
- def deco(func):
- print func
- return func
- @deco
- def foo():pass
- foo()
第一个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(记住一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo))
我写了个小例子,检查函数有没有说明文档:
- def deco_functionNeedDoc(func):
- if func.__doc__ == None :
- print func, "has no __doc__, it's a bad habit."
- else:
- print func, ':', func.__doc__, '.'
- return func
- @deco_functionNeedDoc
- def f():
- print 'f() Do something'
- @deco_functionNeedDoc
- def g():
- 'I have a __doc__'
- print 'g() Do something'
- f()
- g()
(2)有参数装饰器
- def decomaker(arg):
- '通常对arg会有一定的要求'
- """由于有参数的decorator函数在调用时只会使用应用时的参数
- 而不接收被装饰的函数做为参数,所以必须在其内部再创建
- 一个函数
- """
- def newDeco(func): #定义一个新的decorator函数
- print func, arg
- return func
- return newDeco
- @decomaker(deco_args)
- def foo():pass
- foo()
第一个函数decomaker是装饰函数,它的参数是用来加强“加强装饰”的。由于此函数并非被装饰的函数对象,所以在内部必须至少创建一个接受被装饰函数的函数,然后返回这个对象(实际上此时foo=decomaker(arg)(foo))