user3262424
user3262424

Reputation: 7479

Inheritance in Python?

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

Answers (4)

Pete
Pete

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

Niklas R
Niklas R

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

GaretJax
GaretJax

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

Russell Borogove
Russell Borogove

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

Related Questions