Decorator 这个特性,顾名思义,这是一个内置的装饰器模式的实现,利用这个特征在Python里实现AOP易如反掌,这里我分3个部分来说明Decorator 是什么,怎么写,怎么用
首先我们要知道Decorator 是什么。
Decorator r是装饰器模式的实现,那么 简单的来说就是用一个新的对象来替换掉原有的对象,新的对象包含原有的对象,我们可以像调用原有对象一样的来调用新对象,且新对象的创建我们可以控制,所以可以在调用原有对象的时候实现控制。或者将原有对象处理后原样返回。
我们来举一个例子
假设有一个函数
1 def foo():pass
这个方法什么都不做。现在我们定义一个装饰器来扩展这个函数
1 def before(func):
2 def wapper(*args):
3 print "print before invoke foo"
4 return func(*args)
5 return wapper
2 def wapper(*args):
3 print "print before invoke foo"
4 return func(*args)
5 return wapper
这个装饰器方法通过参数func得到被装饰的对象foo 函数(注意:在Python中一切都是对象,包括类和函数),然后定义了一个新的函数来代替原有的函数,并且返回新函数,由于闭包的特性,在定义的新函数内部能够访问到参数func,所以我们在新函数内部,执行被装饰的函数,并且将被装饰的函数的返回值作为新函数的返回值。
1 @before
2 def foo():pass
2 def foo():pass
如上面这般就能用before装饰器来装饰foo函数了。我们执行foo(),就会显示 print before invoke foo。
这是最简单的情况。 下面我们来看装饰函数的Decorator ,装饰类的Decorator ,带参数的Decorator ,用类的方式来写Decorator
在上面的例子我们知道了装饰器的基本形式,被装饰的对象通过第一层函数的参数传入,那么如果装饰的是一个函数,那么第一个参数就是函数对象,如果是类那么就是类的对象。
函数的装饰我们看过了,下面来看一个装饰类的。通常我们调用类的形式都是实例化这个类,所以我们装饰的也是实例化的过程。
1 def single(cls):
2 ins={} #存储所有的类的唯一实例
3 def getins(*args): #用于替代类的装饰方法,返回相当于是类的工厂函数。
4 if cls not in ins: #如果类的实例不在缓存中
5 ins[cls]=cls(*args) #实例化对象,加入缓存
6 return ins[cls] #返回缓存中的唯一实例
7 return getins #返回工厂函数
2 ins={} #存储所有的类的唯一实例
3 def getins(*args): #用于替代类的装饰方法,返回相当于是类的工厂函数。
4 if cls not in ins: #如果类的实例不在缓存中
5 ins[cls]=cls(*args) #实例化对象,加入缓存
6 return ins[cls] #返回缓存中的唯一实例
7 return getins #返回工厂函数