Python – Can a Method That Must Be Overridden Be Private?

inheritancenamingpython

Suppose I have a class C with a method f() which is meant to be used only within C's implementation, but which should be overridden by C's subclasses.

Is it reasonable, or "pythonic", to consider it private, i.e. to name it _f() rather than f()?

In other words would you distinguish the interface provided to subclasses from the interface provided to code outside the inheritance hierarchy?

Best Answer

Pythonically speaking, you should utilize the Abstract Base Class module to implement this functionality.

Example:

from abc import ABCMeta, abstractmethod

class MyBaseClass(object):

    __metaclass__ = ABCMeta

    @abstractmethod
    def f(self, *args):
        #"Public" method (accessible from outside of class instance)
        pass


    @abstractmethod
    def _f(self, *args):
        #"Private" method (should only be accessed from with instance)
        pass

Then this is what happens when you attempt to instantiate a subclass of MyBaseClass without overriding _f():

>>> my_base_class = MyBaseClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyBaseClass with abstract methods _f
>>> class B(MyBaseClass):
...     pass
... 
>>> b = B()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class B with abstract methods _f
>>> class B(MyBaseClass):
...     def _f(self):
...             print "foo"
... 
>>> b=B()
>>> b._f()
foo
>>> 

Note that there are no programmatically "private" methods in Python. That being said, a single underscore before the name (_f()) is used to signify that the method should only be accessed internally.