In Python how to call Parent class function as if I were Parent object

Question:

I have a Parent and a Child class, both should execute their own fct in init but Child have to execute first the Parent fct :

class Parent(object):
    def __init__(self):
        self.fct()

    def fct(self):
        # do some basic stuff
        
class Child(Parent):
    def __init__(self):
        super().__init__()
        self.fct()

    def fct(self):
        # add other stuff
        

Problem is that super().init() calls the Child fct and not the Parent one as I would like. Of course I could rename Child function as fct2 but I was wondering if I can do what I want to do without changing names (because fct and fct2 do the same thing conceptually speaking, they just apply on different things). It would be nice if I could call super().__init() as if were Parent object.

Asked By: Patrick

||

Answers:

The idea of subclassining is this: if you ever need to use a method to the parent class, just do not create it in the child class.

Otherwise, in a hierarchy with complicated classes and mixins, and you really need the methods to have the same name, there is the name mangling mechanism, triggered by Python when using two underlines __ as a method or attribute prefix:

class Parent(object):
    def __init__(self):
        self.__fct()

    def __fct(self):
        # do some basic stuff
        
class Child(Parent):
    def __init__(self):
        super().__init__()
        self.__fct()

    def __fct(self):
        # add other stuff


Using the __ prefix makes Python change the name of this method, both in declaration and where it is used when the class is created (at the time the class statement with its block is itself executed) – and both methods work as if they were named differently, each one only accessible, in an ordinary way, from code in its own class.

Some documentation, mainly older docs, will sometimes refer to this as the mechanism in Python to create "private methods". It is not the samething, although it can serve the same purpose in some use cases (like this). The __fct method above will be renamed respectively to Parent._Parent__fct and Child._Child__fct when the code is executed.

second way, without name mangling:

Without resorting to this name mangling mechanism, it is possible to retrieve attributes from the class where a piece of code is declared by using the __class__ special name (not self.__class__, just __class__) – it is part of the same mechanism Python uses to make argumentless super() work:


class Parent(object):
    def __init__(self):
        __class__.fct(self)   # <- retrieved from the current class (Parent)
 
    def fct(self):
        # do some basic stuff
        
class Child(Parent):
    def __init__(self):
        super().__init__()
        __class__.fct(self) 

    def fct(self):
        # add other stuff

This will also work – just note that as the methods are retrieved from the class object, not from an instance, the instance have to be explicitly passed as an argument when calling the methods.

The name __class__ is inserted automatically in any methods that use it, and will always refer to the class that has the body were it appears – the class itself will be created "in the future", when all the class body is processed and the class command itself is resolved.

Answered By: jsbueno

I think you want to run the fct of the parent before running the fct of the child, if so then this is the code:

class Parent:
    def __init__(self, obj: object):
        self.obj = obj
        self.fct()

    def fct(self):
        # do some basic stuff

class Child:
    def __init__(self, par: Parent):
        self.par = par
        self.fct()

    def fct(self):
        self.par.fct()
        # add other stuff
Answered By: edy131109
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.