Skip to content

Instantly share code, notes, and snippets.

@shininglion
Last active November 23, 2022 01:30
Show Gist options
  • Save shininglion/72b50531d9436844a7eca3e8ffd93b86 to your computer and use it in GitHub Desktop.
Save shininglion/72b50531d9436844a7eca3e8ffd93b86 to your computer and use it in GitHub Desktop.
record function calls in python for replay in the future
class CommandWatcher(object):
def __init__(self):
self.cmd_list = []
def __del__(self):
print("=== command list ===")
print(self.__class__.__name__)
print(self._dumpCmd())
# decorator usage
def record(func):
def wrapped(self, *args, **kwargs):
arg = [str(v) for v in args] + [f"{k}={v}" for k, v in kwargs.items()]
cmd = f"{func.__name__}(" + ", ".join(arg) + ")"
self.cmd_list.append(cmd)
return func(self, *args, **kwargs)
return wrapped
# reimplement __getattribute__
def __getattribute__(self, name):
attr = super().__getattribute__(name)
if callable(attr) and (not name.startswith('_')):
def wrapped(*args, **kwargs):
arg = [str(v) for v in args] + [f"{k}={v}" for k, v in kwargs.items()]
cmd = f"{name}(" + ", ".join(arg) + ")"
self.cmd_list.append(cmd)
return attr(*args, **kwargs)
return wrapped
else:
return attr
def _dumpCmd(self):
return '\n'.join(self.cmd_list)
class MyClass(CommandWatcher):
def __init__(self):
super().__init__()
@CommandWatcher.record
def a(self, v):
print(f"a with {v}")
@CommandWatcher.record
def b(self):
self._internal_z()
return 'b1'
def _internal_z(self):
return 'z'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment