Skip to content

Instantly share code, notes, and snippets.

@KaitoHH
Last active December 4, 2021 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KaitoHH/0e38647f53818a5a85c0fff75432e2b6 to your computer and use it in GitHub Desktop.
Save KaitoHH/0e38647f53818a5a85c0fff75432e2b6 to your computer and use it in GitHub Desktop.
A decorator to decorate a class and all its member function
# Refer to https://kaitohh.com/building-a-class-decorator/ for a complete tutorial
from functools import wraps, partial
def NamedLogger(cls=None, name='default Logger'):
if cls is None:
return partial(NamedLogger, name=name)
@wraps(cls, updated=()) # see https://stackoverflow.com/a/65470430/7620214
class ClassWrapper:
def __init__(self, *cls_args, **cls_kwargs):
# wrap class init
self.old_object = cls(*cls_args, **cls_kwargs)
def __getattr__(self, func_name):
# decorated object method called
target = getattr(self.old_object, func_name)
if not callable(target):
return target
@wraps(target)
def wrapper(*args, **kwargs):
# wrapper method
print(f"{name}: call {func_name}() with args: {args}, kwargs: {kwargs}")
result = target(*args, **kwargs)
print(f"{name}: {func_name}() return: {result}")
return result
return wrapper
return ClassWrapper
@NamedLogger(name='myLogger')
class Adder:
def add(self, a, b):
return a + b
@NamedLogger
class Adder2:
def __init__(self):
self.last = 0
def add(self, a, b):
self.last = a + b
return self.last
if __name__ == '__main__':
adder = Adder()
print(adder.add(1, 2))
adder2 = Adder2()
print(adder2.add(1, 2))
print(adder2.last)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment