Reputation: 13
I'm doing a project where I need to implement debugger decorators applicable to both functions and classes. To explain better I show you the code:
class debug(object):
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
print()
print(f"Calling function: {self.function}")
print(f"args: {args}") ; print(f"kwargs: {kwargs}")
result = self.function(*args, **kwargs)
print(f"result is: {result}")
return result
def _debug(function):
def wrapper(*args,**kwargs):
print()
print(f"Calling function: {function}")
print(f"ARGS: {args}") ; print(f"KWARGS: {kwargs}")
result = function(*args, **kwargs)
print(f"RESULT IS: {result}")
return result
return wrapper
@debug # or @_debug
def foo(x,y):
return x+y
class cdebug(object):
pass
def _cdebug(...):
pass
class pallino(object):
def __init__(self,x,y):
self.x = x
self.y = y
def goo(self):
return self.x+self.y
@cdebug('oops', 'goo') # or @_cdebug('oops', 'goo')
class pinco(pallino):
def __init__(self,x,y,z):
super().__init__(x, y)
self.z = z
def oops(self,a):
return self.x+self.y+self.z-a
if __name__ == '__main__':
foo(10,20)
p = pinco(2,5,7)
p.oops(4)
p.goo()
I had no major problems implementing the debugger decorator applicable to a function, both as a class(debug) and as a function(_debug). But I really have no idea how I could do the debugger decorator applicable to a class, in both versions(cdebug and _cdebug). It should allow me, when I call one of the methods (e.g.: p.goo() or p.oops(..)) that have been passed to the decorator as parameters, to debug them in a similar way as the debugger decorator does for a simple function.
Upvotes: 1
Views: 91
Reputation: 148890
You could build a subclass, and decorate methods of the subclass. That way you do not modify the original class which can be expected from a decorator:
def cdebug(cls):
class wrapper(cls):
pass
for name, method in inspect.getmembers(cls, inspect.isfunction):
# this one will not decorate special methods
if not (name.startswith('__') and name.endswith('__')):
setattr(wrapper,name, _debug(getattr(cls, name)))
return wrapper
Upvotes: 1