修行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