AOPしてみる

python2.4にはDecorators for Functions and Methodsなるものが導入されている。
PEP 318: http://www.python.org/dev/peps/pep-0318/
これを使って、AOPをでっちあげてみた

class Advice:
    def __init__(self, pointcut):
	self.pointcut = pointcut

    def __call__(self, advice):
	def proxy(instance, *args, **kwargs):
	    advice(None, self.pointcut.targetmethod, instance, *args, **kwargs)
	self.pointcut.weaveProxy(proxy)
	return proxy


class MethodJoinPoint:
    def __init__(self, targetmethod):
	self.targetmethod = targetmethod

    def weaveProxy(self, proxy):
	setattr(self.targetmethod.im_class, self.targetmethod.im_func.func_name, proxy)

実際の使い方
ウィーブ対象はHelloクラスのsayMessageメソッド

class Hello:
    def __init__(self, message="Hello, world!"):
	self.message = message
    def sayMessage(self):
	print self.message

sayMessageメソッド呼び出しに対するインターセプターは以下のように書く

"""
>>> hello.Hello("Hello, aspect!").sayMessage()
before
Hello, aspect!
after
>>> DerivedHello("Hello, subtype!").sayMessage()
before
Hello, subtype!
after
"""
import hello
import aspect

class DerivedHello (hello.Hello):
    pass

class Trace:
    
    @aspect.Advice(aspect.MethodJoinPoint(hello.Hello.sayMessage))
    def f(self, target, instance, *args, **kwargs):
	print "before"
	target(instance, *args, **kwargs)
	print "after"
	

if __name__ == '__main__':
    import doctest
    doctest.testmod()

DerivedHelloクラスはサブクラスだが、こちらにもインターセプターはきいている