I was trying to perform an action before and after the execution of some methods in my class.
First I thought about using a decorator to extend the functionality, something like this:
def decorator(f):
def wrap(*args, **kwargs):
print("before")
f(*args, **kwargs)
print("after")
return wrap
class Foo(object):
@decorator
def do(self):
print("This is do")
a = Foo()
a.do()
This outputs what I want:
before
This is do
after
But then I realized that if I wanted to inherit from Foo to extend do that wouldn't work, at least the way I'm doing it:
class Bar(Foo):
def do(self):
super(Bar, self).do()
print("This is the new implementation of do")
b = Bar()
b.do()
This will be the output and it's not okay. "after" should be the last thing to be printed:
before
This is do
after
This is the new implementation of do
Maybe there is another way to decorate do in Bar so it does what I want but I don't know how (if there is I would like to know it) and tbh decorating do every time doesn't seem like a good way to go.
So finally I came up with what I think is a nice solution. Defining __getattribute__so it returns a wrapper for do:
class Foo(object):
def __getattribute__(self, name):
attribute = super(Foo, self).__getattribute__(name)
if name == "do":
def wrap(*args, **kwargs):
print("before")
attribute(*args, **kwargs)
print("after")
return wrap
else:
return attribute
def do(self):
print("This is do")
class Bar(Foo):
def __init__(self):
super(Bar, self).__init__()
def do(self):
super(Bar, self).do()
print("This is the new implementation of do")
a = Bar()
a.do()
Is this a good solution? Any downsides? I'm missing something that could create a problem in the future? Other workarounds?
Thx!!