I have a class hierarchy in which subclasses may optionally define a method with a given name, say do_it
, and want to write a function, say do_all
, in the base class that ensures that each such method will be executed, in order of class hierarchy. The closest I can get to achieving this is something like:
class A(object):
def do_it(self):
print 'Do A'
def do_all(self):
# Better, from comments and answers: vars(type(self))
for c in reversed(self.__class__.__mro__[:-1]):
c.do_it(self)
class B(A):
def do_it(self):
print 'Do B'
class C(B):
def no_do_it(self):
pass
class D(C):
def do_it(self):
print 'Do D'
This almost works as intended, for example B().do_all()
gives
Do A
Do B
But it results in a duplicate call to B
s do_it
for all classes descended from it. For example D().do_all()
gives
Do A
Do B
Do B
Do D
How can I avoid the duplicate call to a parent's do_it
from classes that do not implement it? Is this even the right way to achieve what I'm trying to do?
You can check whether the function has already been seen:
Note that in Python 2 you'll need to extract the function from the unbound method, as
c.do_it.__func__
(or usesix.get_unbound_function
).An alternative is to examine
__dict__
: