-
-
Save williamsjj/184047 to your computer and use it in GitHub Desktop.
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 time | |
from traceback import extract_stack, format_list | |
def wrap_func(base_class): | |
def check_func(f): | |
old_func_name = 'old%s' % (f.__name__,) | |
if hasattr(base_class, f.__name__): | |
setattr(base_class, old_func_name, | |
getattr(base_class, f.__name__)) | |
def new_func(*args, **kwargs): | |
f(*args, **kwargs) | |
if hasattr(base_class, old_func_name): | |
return getattr(base_class, old_func_name)(*args, **kwargs) | |
setattr(base_class, f.__name__, new_func) | |
return new_func | |
return check_func | |
def record(base_class): | |
"""Record the interactions on a specific class. | |
This method will take a class and wrap __setattr__ and record any time a | |
__setattr__ occurs with the name, value, time and *where* it was set from | |
via. the stack. Any potential name clashes after being wrapped first call | |
the wrapper's functions and then the base class'. The eventual, return | |
value will be from your function and not this class. To get any object's | |
history after being wrapped by this class, just call dump_history(). | |
Usage: | |
@record | |
class A: | |
foo = 1 | |
bar = A() | |
bar.foo = 2 | |
bar.dump_history() | |
At runtime (or in the interpreter), instead of using the class decorator, | |
you can use: | |
A = record(A) | |
""" | |
@wrap_func(base_class) | |
def __init__(self, *args, **kwargs): | |
self._history = [] | |
@wrap_func(base_class) | |
def __setattr__(self, key, value): | |
if key != "_history": | |
self._history.append((key, value, time.time(), | |
extract_stack()[:-1])) | |
if not hasattr(self, 'old__setattr__'): | |
self.__dict__[key] = value | |
@wrap_func(base_class) | |
def dump_history(self): | |
for key, value, t, stack in self._history: | |
print '%s = %s' % (key, value) | |
print '@= %s' % (t,) | |
print ''.join(format_list(stack)) | |
print '--------------------' | |
return base_class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment