修行Python个把星期,终于有点成果了,呵呵,一个利用metaclass实现的aop。
其实python这类非常动态的语言要实现AOP是很容易的,所以首先我们要来先定义一个metaclass
然后我们要在__new__()这个metaclass 的时候动态植入方法到要调用地方法的前后。
具体代码如下:
class pyaop(type):
'''
这个空方法是用来将后面的beforeop和afterop初始化成函数引用
'''
def nop(self):
pass
'''
下面这两个变量是类变量,也就是存放我们要植入的两个函数的地址的变量
'''
beforeop=nop
afterop=nop
'''
设置前后两个植入函数的类函数
'''
@classmethod
def setbefore(self,func):
pyaop.beforeop=func
@classmethod
def setafter(self,func):
pyaop.afterop=func
'''
初始化metaclass的函数,这个函数最重要的就是第四个参数,dict通过这个参数我们可以修改类的属性(方法)
'''
def __new__(mcl,name,bases,dict):
from types import FunctionType #加载类型模块的FunctionType
obj=object() #定义一个空对象的变量
'''
这个就是要植入的方法,func参数就是我们要调用的函数
'''
def aop(func):
'''
我们用这个函数来代替将要调用的函数
'''
def wrapper(*args, **kwds):
pyaop.beforeop(obj) #调用前置函数
value = func(*args, **kwds) #调用本来要调用的函数
pyaop.afterop(obj) #调用后置函数
return value #返回
return wrapper
#在类的成员列表中查找即将调用的函数
for attr, value in dict.iteritems():
if isinstance(value, FunctionType):
dict[attr] = aop(value) #找到后用aop这个函数替换之
obj=super(pyaop, mcl).__new__(mcl, name, bases, dict) #调用父类的__new__()创建self
return obj
class A(object):
__metaclass__ = pyaop
def foo(self):
total = 0
for i in range(100000):
total = total+1
print total
def foo2(self):
from time import sleep
total = 0
for i in range(100000):
total = total+1
sleep(0.0001)
print total
def beforep(self):
print('before')
def afterp(self):
print('after')
if __name__ == "__main__":
pyaop.setbefore(beforep)
pyaop.setafter(afterp)
a=A()
a.foo()
a.foo2()
转自:http://www.cnblogs.com/Alexander-Lee/archive/2008/12/06/pythonaop.html