Reputation: 57
class C(Test):
def __init__(self):
print "in C init"
super(C, self).__init__()
def setup(self):
print "\tin C setup"
def runtest(self):
print "\t\tin C runtest"
def teardown(self):
print "\t\t\tin C teardown"
I have such classes in different modules. For eg class A
,B
,C
etc.. In one module I'm considering only classes who have setup and teardown methods. Suppose Class A
doesn't have setup method, I don't want to consider it for further parth of my program where I'm building list of classes having setup and runtest module. Is there any python function I can use for the same? What is the correct way to deal with this problem?
Upvotes: 2
Views: 8129
Reputation: 8091
You can use hasattr
and callable
on the classes themselves (classes are objects afterall), i.e. something like
if hasattr( C, 'setup' ) and callable( C.setup ):
classes_with_setup.append(C)
or, in terms of a list comprehension
classes_with_setup=[ U for U in [A,B,C...] if hasattr(U,'setup') and callable(U.setup)]
to setup your list of classes with those features.
This methodology does detect inheritance:
In [1]: class A(object):
...: def f(self):
...: print 'hi'
...:
In [2]: class B(A):
...: pass
...:
In [3]: hasattr(A,'f')
Out[3]: True
In [4]: hasattr(B,'f')
Out[4]: True
In [5]: hasattr(B,'f') and callable(B.f)
Out[5]: True
Upvotes: 4
Reputation: 89017
I would argue this is a case for an abstract base class.
class Test(metaclass=ABCMeta):
@abstractmethod
def setup(self):
...
@abstractmethod
def teardown(self):
...
@classmethod
def __subclasshook__(cls, C):
if cls is Test:
if (any("setup" in B.__dict__ for B in C.__mro__) and
any("teardown" in B.__dict__ for B in C.__mro___)):
return True
return NotImplemented
This defines the type Test
, and a __subclasshook__
function that checks if a class defines setup()
and teardown()
. This means any such class will be treated as a subclass of Test
- that is issubclass()
will return True
for issubclass(C, Test)
.
Of course, you could just do the check manually using the same methodology as the __subclasshook__
function, but abstract base classes provide a nice (and standard) way to define the contract you want fulfilled.
Upvotes: 5
Reputation: 22697
You can use getattr
and callable
methods
setup_method = getattr(your_object, "setup_method", None)
if callable(setup_method):
setup_method(self.path.parent_op)
First check if the object has an attribute called "setup_method
" then check it that attribute is a method and then call it.
Upvotes: 2