Search code examples
pythonclasssuper

How to call the instance method of the parent class?


I found a way, as follows instance :

Change the instance method to the class method to achieve the result I want.

class MyClassA:
    name = 'MyClassA'

    def __init__(self):
        self.name = 'instance name'
        self.print_name()
        pass

    @classmethod
    def print_name(cls):
        name = cls.name
        print(name)

    @classmethod
    def init(cls):
        cls.name = 'class name'


class MyClassB(MyClassA):
    pass


MyClassB.init()
c1 = MyClassB()


I want to set MyClassB.name='class name' and get MyClassB.name.

How to modify the code?

class MyClassA:
    name = 'MyClassA'

    def __init__(self):
        self.name = 'instance name'
        self.print_name()
        pass

    def print_name(self):
        name = super().name
        print(name)

    @classmethod
    def init(cls):
        cls.name = 'class name'


class MyClassB(MyClassA):
    pass


MyClassB.init()
c1 = MyClassB()

I want to call the method c1.print_name() of the parent class instance in the subclass.

How to modify the code to get the output:'class name'

My code is as follows:

class MyClassA:
    def __init__(self):
        self.print_name()
        pass

    def print_name(self):
        name = super().name
        print(name)

    @classmethod
    def init(cls):
        cls.name = 'class name'


class MyClassB(MyClassA):
    pass


MyClassB.init()
c1 = MyClassB()

The error is as follows:

Traceback (most recent call last):
  File "D:\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3437, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-0a688d5bfaa6>", line 20, in <module>
    c1 = MyClassB()
  File "<ipython-input-3-0a688d5bfaa6>", line 3, in __init__
    self.print_name()
  File "<ipython-input-3-0a688d5bfaa6>", line 7, in print_name
    name = super().name
AttributeError: 'super' object has no attribute 'name'

Solution

  • super().name is looking for an attribute called name on the parent class - i.e. MyClassA - which obviously doesn't exist.

    Since you have added the attribute name to MyClassB you should access it as self.name - e.g.:

    class MyClassA:
        def __init__(self):
            self.print_name()
            pass
    
        def print_name(self):
            name = self.name
            print(name)
    
        @classmethod
        def init(cls):
            cls.name = 'class name'
    
    
    class MyClassB(MyClassA):
        pass
    

    To answer your new 'upper' question, if you want to set a specific name attribute, which defaults to a but becomes b for MyClassB then you need to override this when instantiating:

    class MyClassB(MyClassA):
        def __init__(self):
            # Call the parent class' super method (sets name == a)
            super().__init__()
            # Override name
            self.name = 'b'