======================================= Aspect-oriented Programming for Dummies ======================================= $Id$ >>> from cybertools.util.aop import getNotifier >>> class Demo(object): ... def foo(self, num): ... return 38 + num >>> demo = Demo() >>> demo.foo(4) 42 >>> wrappedFoo = getNotifier(demo.foo) >>> demo.foo is wrappedFoo True Repeated calls of ``getNotifier()`` return the same wrapped object. >>> getNotifier(demo.foo) is wrappedFoo True Calling the wrapped method still works. >>> demo.foo(8) 46 We can now get information about the start and end of the method call by subscribing to it using a logging routine. >>> def log(result, msg): ... print 'logging: %s, result=%s' % (msg, str(result)) >>> demo.foo.subscribe(log, None, 'before foo') >>> demo.foo(4) logging: before foo, result=None 42 >>> demo.foo.subscribe(log, log, "that's foo") >>> demo.foo(4) logging: before foo, result=None logging: that's foo, result=None logging: that's foo, result=42 42 Wrapping methods on class level =============================== The above code did only wrap the bound method ``foo()`` of a certain instance of the ``Demo`` class. Other instances of this class are not affected. >>> demo = Demo() >>> demo.foo(4) 42 But we may also wrap the class itself and subscribe to the method on the class level. >>> getNotifier(Demo.foo) <...Notifier object ...> >>> Demo.foo.subscribe(None, log, 'after foo') This now affects all instances of the class. >>> demo.foo(4) logging: after foo, result=42 42 >>> demo.foo(8) logging: after foo, result=46 46 Combining class and instance level wrapping ------------------------------------------- >>> demo.foo.subscribe(None, log, 'after demo.foo') >>> demo.foo(10) logging: after demo.foo, result=48 logging: after foo, result=48 48