Reputation: 5945
I am looking for advice on how to construct some project I gonna work on.
I got a base class, with some methods.
class Base(object):
def method1(self):
# some code
def method2(self):
# some code
def method3(self):
# some code
... and some other methods
For my project, I cannot modify the Base class, and I must inherent from it in order to apply my project requirements.
I have several requirement that might be enabled or not. Depending on a given configuration. I.e. I'd like to be able to override either method1(), method2(), method3() or any combination of them.
One alternative is to construct several inheriting classes.
class Child1(Base):
def method1(self):
# some code
class Child2(Base):
def method2(self):
# some code
class Child3(Base):
def method3(self):
# some code
And then maybe use multiple inheritance to apply any composition of them. However this approach wouldn't scale well for covering all possible combinations.. (e.g. what happens if I will have Child4()? )
Another alternative is just having a single inheritance class and use if
clauses to select whether to call the super method or apply the derived behavior.
class Child(Base):
def method1(self):
if not self.override1:
# call super
else:
# some code
def method2(self):
if not self.override2:
# call super
else:
# some code
def method3(self):
if not self.override3:
# call super
else:
# some code
I am more in favor on this alternative, however I feel there got to be a better OO approach for doing this.
Any thoughts or suggestions?
Thanks a lot
PS: I am constrained to python 2.7, and since I plan to share the code, I rather have a solution that is easy to understand by an average python programmer (and not only by advanced programmers).
Upvotes: 2
Views: 105
Reputation: 15310
Keep in mind that class definitions are executed code. You could conditionally define or ignore a method in your child class:
class Child(Base):
if something:
def method1(self, etc):
pass
Here's an example. Note that setting the condition has to happen before the class definition - this is not a dynamic parameter:
#!python3
import sys
special = False
if "--special" in sys.argv:
special = True
class Base:
def method1(self):
print("Base method1")
def method2(self):
print("Base method2")
class Child(Base):
def method3(self):
print("Child method3")
if special:
def method1(self):
print("Child method1")
ch = Child()
ch.method1()
ch.method2()
ch.method3()
Output is:
$ python test.py --special
Child method1
Base method2
Child method3
$ python test.py
Base method1
Base method2
Child method3
Upvotes: 1
Reputation: 23753
I like the first choice it seems manageable, no code duplication:
class A:
def one(self):
return 'one |'
def two(self):
return 'two |'
def three(self):
return 'three |'
def four(self):
return 'four |'
class B(A):
def one(self):
return 'one foo |'
class C(A):
def two(self):
return 'two foo |'
class D(A):
def three(self):
return 'three foo |'
class BC(B, C):
pass
class CD(C, D):
pass
class BD(B, D):
pass
Now you have seven things to choose from. If needed you can easily tell what kind of thing it is at run-time:
>>> bc = BC()
>>> isinstance(bc, A)
True
>>> isinstance(bc, CD)
False
>>> isinstance(bc, BC)
True
And you'll probably find out you forgot something and it is easy to add:
#oops now I need this
class X(A):
def four(self):
pass
# and this $#%^!*
class B1(A):
def one(self):
return 'one bar |'
Upvotes: 2