Please see the code below. Part of the explanation is:
B's constructor calls its direct superclass's constructor via line
super().__init__(y)
(super()
returns a reference to the direct superclass). so, objectb
inherits propertyx
and its value is set to2
since this is the default value inB
's constructor when no parameter is provided.So, after object
b
is created,b.x
has a value of2
."
My question is: How does b.x
get a value of 2
? Shouldn't class B
's super().__init__()
also contain an x
variable since the superclass (A
) has x
in its constructor?
My observation is that whatever the value of y is in class B
's own constructor (in this case y=2
), that becomes the value of b.x
class A:
def __init__(self, x=5):
self.x = x
class B(A):
def __init__(self, y=2):
super().__init__(y)
def set(self, y):
self.x = y 3
return self.x
b = B()
print(b.set(b.x 2))
#result is 7
CodePudding user response:
The fact that you call super().__init__(y)
is irrelevant to the fact that A
's initializer accept an argument into the name x
. The name received only matters if you pass the name by keyword. If you wanted to pass the name by keyword, obviously super().__init__(y=y)
wouldn't work (A
doesn't receive an argument named y
), but super().__init__(x=y)
would work just fine, because it doesn't matter a whit what the caller calls their own variable (or lack thereof when passing a literal value), it just matters that it's passed in the correct position or with the correct keyword name.
Your toy example is very weird (the subclass is violating the Liskov substitution principle, in that B(y=1)
works, but A(y=1)
would not work), which is probably confusing you more, but the point it makes is valid: When you pass arguments positionally, it does not matter what the receiver calls the parameter, nor does it matter what the caller calls it.
CodePudding user response:
It's because you assigned a new value to x when you created the super-class constructor, so you can get away with removing y from the super().init(y), and that should give you the original value x=5
Example:
class A:
def __init__(self, x=5):
self.x = x
class B(A):
def __init__(self, y=2):
super().__init__() # removed y
def set(self, y):
self.x = y 3
return self.x
b = B()
print(b.set(b.x 2))
Hope that helped