0

In the below code Class B inherits from Class A, and the variables of Class A are assigned through Class B. I have created two new instances of Class B using Check1 and Check2 as shown below:

class ClassA:
      def __init__(self, a, b):
          self.A = a
          self.B = b

   
class ClassB(ClassA):
    def __init__(self, a, b):
        ClassA.A = a
        ClassA.B = b

    def printB(self):
        print("B = "+str(ClassA.A + ClassA.B))



if __name__ == '__main__':
    print('#### Part I - using Check1 ######')
    Check1 = ClassB(1,2)
    Check1.printB()
    print('#### Part II -  Using Check2 ######')
    Check2 = ClassB(5,6)
    Check2.printB()
    print('#### Part III -  Again Using Check1 ######')
    Check1.printB()

I get the following output:

#### Part I - using Check1 ######
B = 3
#### Part II -  Using Check2 ######
B = 11
#### Part III -  Again Using Check1 ######
B = 11

My question is why do I get B=11 when calling the Check1 in Part III ? Shouldn't python be creating a new instance of even the parent class for Check1 object, and shouldn't Check1 display the output as B=3 ?

How can I modify the above code so that Check1 can have value as B=3 when I call it in Part III?

3
  • you are assigning values to clsss variables not object variables. you need to create and instance of class A in class B's init and then assign Commented Feb 5, 2021 at 2:08
  • You're assigning class variables (not instance variables) in your ClassB constructor. Whatever value you passed in last is now shared by the entire class. Commented Feb 5, 2021 at 2:08
  • There is only one ClassA here. Every reference to ClassA.A (for example) is to exactly the same class attribute. Commented Feb 5, 2021 at 2:08

3 Answers 3

1

You're not implementing inheritance correctly -- assigning to ClassA's members overwrites the class object iself, not the inherited instance attributes (which are still accessed via self). In addition, you don't want to copy and paste the parent constructor; instead you should just call it directly.

class ClassA:
      def __init__(self, a, b):
          self.A = a
          self.B = b

   
class ClassB(ClassA):
    def __init__(self, a, b):
        ClassA.__init__(self, a, b)

    def printB(self):
        print("B = "+str(self.A + self.B))
Sign up to request clarification or add additional context in comments.

Comments

1

You seem to be under the impression that a Python object has separate instance variable namespaces for each of its classes, or that Python objects have C++-style base class subobjects. That's not how Python works.

When you create an instance of ClassB, you're only making one object, which is an instance of both ClassA and ClassB. There's no separate ClassA instance. When your ClassB.__init__ does

ClassA.A = a
ClassA.B = b

that doesn't mean "set the instance variables declared in ClassA", or "set the instance variables on some instance of ClassA attached to this object". This line assigns to class variables on ClassA, not instance variables on any object. (Also, you never delegated to the superclass constructor, so ClassA.__init__ gets skipped entirely.)

Class variables are global state - separate instances don't get separate copies. Creating Check2 overwrites the values set when creating Check1.


It looks like the behavior you want from ClassB's constructor is exactly the behavior of ClassA's constructor, so you can just inherit __init__. You don't need to write a separate __init__.

As for printB, that needs to access instance variables:

class ClassB(ClassA):
    def printB(self):
        print("B = "+str(self.A + self.B))

Comments

0

What you are trying to do in ClassB's __init__ method, super() can do for you (also what you're doing is not correct as others have pointed out). This way you don't have to repeat code and can initialise attributes only in the base class:

class ClassA:
    def __init__(self, a, b):
        self.A = a
        self.B = b

class ClassB(ClassA):
    def __init__(self, a, b):
        super().__init__(a=a, b=b)

    def printB(self):
        print("B = "+str(self.A + self.B))  

And the output:

Check1 = ClassB(1,2)
Check1.printB()
B = 3

Check2 = ClassB(5,6)
Check2.printB()
B = 11

Check1.printB()
B = 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.