override "private" method in Python

Ernest A picture Ernest A · Feb 15, 2013 · Viewed 11.2k times · Source

Consider a class with a "private" method such as:

class Foo(object):
    def __init__(self):
        self.__method()
    def __method(self):
        print('42')

When I try to subclass Foo and override method __method, it can be seen that Foo.__method is still called, instead of MoreFoo.__method.

class MoreFoo(Foo):
    def __method(self):
        print('41')

>>> MoreFoo()
42
<__main__.MoreFoo object at 0x7fb726197d90>

What would be the way to override such a method?

Answer

Martijn Pieters picture Martijn Pieters · Feb 15, 2013

The point of using the double-underscore name convention is to prevent subclasses from (accidentally) overriding the method.

If you have to override it anyway, someone made a serious class design error. You can do it still, by naming your object just so:

def _Foo__method(self):

where you prefix the method name with one more underscore and the defining classname (so in this case prefixed with _Foo). The process of renaming methods and atributes with a double underscore is called private name mangling.

If you want to define a 'private' method that is still overridable in a subclass, you generally stick to names with one underscore instead (def _method(self):).

Due to it's dynamic nature, almost nothing in Python is truly private; with a little introspection almost anything can be reached.