0

I'm trying to use a parent method from a child class. A bare bone example is given below.

class one:
    def multiply(self, x, y):
        self.x = 500
        return self.x*y
        
class two(one):
    def multiplier(self, x, y):
        self.x = x
        
        ver1 = one.multiply(one, self.x, y)  # here, if I don't pass one as an argument, I get a TypeError
        print('The answer of ver1:', ver1)
        print('What is self.x btw?', self.x)
        
        ver2 = super().multiply(self.x, y)
        print('The answer of ver2:', ver2)
        print('What is self.x now?', self.x)

t = two()
t.multiplier(3,4)

This prints:

The answer of ver1: 2000
What is self.x btw? 3
The answer of ver2: 2000
What is self.x now? 500

I looked on here and many answers seem to imply that ver2 is the correct way to call a parent method but I don't want self.x to change in the child class, so the answer I want is ver1. But, in ver1, it seems redundant to pass one as an argument when it is already specified that multiply is one's method (if I don't pass one as an argument, I get

TypeError: multiply() missing 1 required positional argument: 'y'

So what is the correct way to call a method from a parent class without changing variables in the child class?

Lakshya Raj
  • 1,669
  • 3
  • 10
  • 34
  • 1
    Worry about defining classes that model things sensibly first. The only reason this works is because you are taking advantage of the fact that you can attach attributes to a class object when you pass `one`, rather than an instance of `one`, as the first argument to `one.multiply`. – chepner Jan 27 '21 at 18:46
  • See https://stackoverflow.com/questions/805066/how-to-call-a-parent-classs-method-from-child-class-in-python – Stefan Jan 27 '21 at 18:49
  • @chepner so what's the sensible way to defining classes? I'm completely new to this thing and don't exactly understand what you're saying. –  Jan 27 '21 at 19:24
  • 1
    Don't use instance methods if you don't actually have an instance of the class. – chepner Jan 27 '21 at 20:08
  • You are passing the class `one` as the `self` argument of `multiply`. This makes very little sense... You are not overriding `multiply` so it exists in the child class. Just use `self.multiply(self.x, y)` – Tomerikoo Jan 28 '21 at 11:02

1 Answers1

-1

Use self, not one:

class two(one):
    def multiplier(self, x, y):
        self.x = x
        
        ver1 = self.multiply(x, y)
        print('The answer of ver1:', ver1)
        print('What is self.x btw?', self.x)

Super is useful if you override the same method but want access to the parent:

class two(one):
    def multiply(self, x, y):
        self.x = x
        
        ver2 = super().multiply(x, y)
        print('The answer of ver2:', ver2)
        print('What is self.x now?', self.x)

It seems redundant to pass one as an argument when it is already specified that multiply is one's method (if I don't pass one as an argument, I get TypeError: multiply() missing 1 required positional argument: 'y')

This is because when you use self, the method is bound to the instance and the instance is passed automatically as first parameter. When using one.multiply, the method is not bound and you need to pass it manually. But this is not the right way to go, as you intuited.

I don't want self.x to change in the child class

There are two classes and an instance which is an instance of both classes due to inheritance. x is an instance attribute, so it belongs to the instance, not to any of both classes. It can't change in parent and not child class or the opposite.

Jérôme
  • 13,328
  • 7
  • 56
  • 106