Reputation: 7479
Suppose that I have the following python
base class:
class BaseClass(object):
def a():
"""This method uses method b(), defined in the inheriting class"""
And also a class that inherites BaseClass
:
class UsedByUser(BaseClass):
def b():
"""b() is defined here, yet is used by the base class"""
My user would only create instances of class UsedByUser
. Typical use would be:
if __name__ == '__main__':
# initialize the class used by the user
usedByUser = UsedByUser()
# invoke method a()
usedByUser.a()
My questions is, is the above use problematic? is this a valid approach, or must I also define method b()
in BaseClass
and then override it in UsedByUser
?
Upvotes: 3
Views: 1239
Reputation: 10680
Sounds like you want A
to call a protected member function of UsedByUser
that can't go in the abstract BaseClass
). Try prefixing the protected function with an underscore (although note this is just a convention used by Python and not strictly checked, as mentioned here).
class BaseClass(object):
def A(self):
print "Grettings from A"
self._B()
def _B(self):
raise NotImplementedError('b must be implemented by a subclass')
class UsedByUser(BaseClass):
def _B(self):
""" prefix with underscore is a python convention for a protected member function """
print "B rocks!"
if ( __name__=='__main__' ):
usedByUser = UsedByUser()
usedByUser.A()
Find more on this convention in the PEP guidelines.
Edit:
As GaretJax suggested, I added a BaseClass
_B
method for clarity. Nice tip!
Upvotes: 0
Reputation: 16860
The use is correct. Classes can define methods that can be overriden
from subclasses, but those can also define new methods. Defining
every method needed for subclasses in the superclass seems a bit
senseless. (Since object
then would also need to have every
function defined ?)
A subclass often has a different bahviour to another subclass.
class Vehicle(object): def Refuel(self): # ...
class Plane(Vehicle): def Fly(self): # ...
class Car(Vehicle): def Drive(self): # ...
Edit: I misread the code.
If only you create a subclass of it and make sure subclasses have B()
, then it's theoratically ok, but bad style. It makes more sense and is safer to give the superclass attributes and methods that are used by the superclass. -> Define B()
Upvotes: 0
Reputation: 7780
I would define the b
method in the BaseClass
too:
class BaseClass(object):
def b(self):
raise NotImplementedError('b must be implemented by a subclass')
Remember: explicit is better than implicit and given that the method a
needs the method b
anyways, better raise a meaningful exception rather than a general AttributeError
.
It is worth to point out that this is absolutely NOT needed from a syntactic point of view, but it adds clarity to the code and enforces the subclass to provide an implementation.
Upvotes: 7
Reputation: 19037
BaseClass can't assume that a UsedByUser object exists, so it can't use a B() method from it. You probably want to define a B() in BaseClass, that either does nothing (if it's sensible to attempt B() with something that doesn't support it) or raises an exception (if it's not sensible to attempt B()).
If you tell us what A and B are in your use case, we may be able to advise you better.
Upvotes: -1