Created
May 5, 2011 13:41
-
-
Save aandr/957043 to your computer and use it in GitHub Desktop.
Python AOP using Class Decorators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import inspect | |
def aspectize(arg): | |
def decorate_method(func): | |
func.__before = [] | |
func.__after = [] | |
def decorated(*args, **kwargs): | |
for f in func.__before: | |
res = f(*args, **kwargs) | |
if res is not None: | |
return res | |
main_res = func(*args, **kwargs) | |
for f in func.__after: | |
res = f(main_res, *args, **kwargs) | |
if res is not None: | |
return res | |
return main_res | |
decorated.__before = func.__before | |
decorated.__after = func.__after | |
return decorated | |
if inspect.isclass(arg): | |
for attr in arg.__dict__: | |
if callable(arg.__dict__[attr]): | |
setattr(arg, attr, decorate_method(arg.__dict__[attr])) | |
return arg | |
elif callable(arg): | |
return decorate_method(arg) | |
else: | |
raise Exception("Don't know what to do with argument") | |
def before(method): | |
def decorator(advice): | |
method.__before.append(advice) | |
return decorator | |
def after(method): | |
def decorator(advice): | |
method.__after.append(advice) | |
return decorator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from aop import aspectize, before, after | |
""" | |
Example: | |
>>> x = MyClass() | |
>>> x.my_func() | |
6 | |
my_func returned 6 | |
6 | |
>>> x.my_func() | |
7 | |
my_func returned 7 | |
7 | |
>>> x.my_func() | |
8 | |
my_func returned 8 | |
8 | |
""" | |
@aspectize | |
class MyClass: | |
def __init__(self): | |
self.x = 5 | |
def my_func(self): | |
print(self.x) | |
return self.x | |
@before(MyClass.my_func) | |
def increase_x(self): | |
self.x += 1 | |
@after(MyClass.my_func) | |
def log_my_func(res, self): | |
print("my_func returned " + str(res)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi,there is something wrong with this code snippet.i got this error when i run this code:
Traceback (most recent call last):
File "/projects/achilles/app/base/aop_demo.py", line 22, in
@before(HandleClass.incr)
AttributeError: 'NoneType' object has no attribute 'incr'
(py 2.7)
that is how my code looks like: