I have the following situation in my python code:
class Parent(object):
def run(self):
print "preparing for run"
self.runImpl()
print "run done"
class Child(Parent):
def runImpl(self):
print "child running"
However, I have cases with several generations of such 'decorators', doing different setup/teardown steps before and after 'runImpl', and currently I am forced to define run()
, runImpl()
and runImplSingleProcess()
in my classes Parent
, Child
and ChildSingleProcess
.
I am looking for a solution of the following form:
class Parent(object):
@wrapping_child_call
def run(self, func_impl, *args, **kwargs)
print "preparing for run"
func_impl(*args, **kwargs)
print "run done"
class Child(Parent):
def run(self):
print "child running"
In this way, there is almost no need for Child class to be aware of this going on.
There may also be an issue with multiple inheritance. If a Child
inherits from Parent1
and Parent2
, I honestly don't know what should be the correct behavior.
Does anyone know a good, natural, way of accomplishing this? or am I raping the design here?
Thanks
Yonatan
Yonatan, your question isn't clear! Depending on the situation you could use many different designs.
One solution would be to have explicit setup() and teardown() methods which are called by the run() method before calling runImpl(). This would allow subclasses to wrap/override these as needed.
However, you mentioned multiple inheritance, which means this isn't the direction you should be taking at all.
Your mentioning multiple inheritance and wrapping (as in "decorators") leads me to guess that you want to be able to write different "runner" implementations, each with its own setup/teardown process, while re-using pieces of setup/teardown between different "runners".
If this is the case, you could define resources which know how to setup and teardown themselves, and have each runner would declare which resources it requires. The run() method would run the relevant setup/teardown code of each resource and make them available to the runImpl() method.
You can get this:
With:
(Python 2 only)
Don't use inheritance here
Invert your design. Instead of a parent-child implementation which is a "is-a" relationship why not just have a composition so you get a "has-a" relationship? You could define classes which implement the methods you'd like while your previous parent class would be instantiated with those implementation specific classes.