Python class default value inheritance
I did some tests today :
class SuperC():
def __init__(self, a, b, c, d='D0'):
self. A = a
self. B = b
self. C = c
self. D = d
self. E = 'E0'
sup = SuperC('A0', 'B0', 'C0')
print(sup. A) # >>> A0
print(sup. B) # >>> B0
print(sup. C) # >>> C0
print(sup. D) # >>> D0
print(sup. E) # >>> E0
You can see in the Super Class that there are two types of default values (d
and e
)
d
is more “open”, while e
is a bit “hidden”
Now, if I create a subclass with a new attribute “f”:
class SubC1(SuperC):
def __init__(self, a, b, c, f):
super().__init__(a, b, c)
self. F = f
sub1 = SubC1('A1', 'B1', 'C1', 'F1')
print(sub1. A) # >>> A1
print(sub1. B) # >>> B1
print(sub1. C) # >>> C1
print(sub1. D) # >>> D0
print(sub1. E) # >>> E0
print(sub1. F) # >>> F1
I can see that a,b,c
are well inherited and can accept the new values.
But I didn’t choose to have d
and e
in super().__init__().
But they also get perfect inheritance, the problem is that I can’t change the values of d
and e
when creating an instance of the subclass. f is
working properly.
Now I’ll create another subclass:
class SubC2(SuperC):
def __init__(self, a, b, c, f, d='D2'):
super().__init__(a, b, c, d)
self. F = f
sub2 = SubC2('A2', 'B2', 'C2', 'F2')
print(sub2. A) # >>> A2
print(sub2. B) # >>> B2
print(sub2. C) # >>> C2
print(sub2. D) # >>> D2
print(sub2. E) # >>> E0 # hidden e is still E0
print(sub2. F) # >>> F2
With d is written in __init__
() and super().__init__(),
now d
can be perfectly inherited and can be overridden by a new default or a new value in a new instance. But e
is still E0
It seems that the only good way is:
class SubC3(SuperC):
def __init__(self, a, b, c, f, d='new D', e='new E'):
super().__init__(a, b, c)
self. D = d # set new
self. E = e # set new
self. F = f
sub3 = SubC3('A3', 'B3', 'C3', 'F3')
print(sub3. A) # >>> A3
print(sub3. B) # >>> B3
print(sub3. C) # >>> C3
print(sub3. D) # >>> new D
print(sub3. E) # >>> new E
print(sub3. F) # >>> F3
Now I can have both d
and e
and brand new default/instance values, but if not specified, then they will not inherit from SuperC
My question is, am I thinking correctly?
Am I missing something?
Is there a better way to set default inheritance?
Or in some way, if written this way, the e
should not be changed? Because it might be a basic property that should be a constant value for both the parent (super class) and the child class?
Solution
I don’t seem to understand the question….
When you do:
class SuperC():
def __init__(self, a, b, c, d='D0'):
self. A = a
self. B = b
self. C = c
self. D = d
self. E = 'E0'
self. E
is not “hidden”. It just received a hard-coded value: the strings “E0” and d='D0'
can be read as If you are in the d
parameter, use that parameter, otherwise, just use the string “D0"
(it is one named optional argument )
When you do:
class SubC3(SuperC):
def __init__(self, a, b, c, f, d='new D', e='new E'):
super().__init__(a, b, c)
self. D = d # set new
self. E = e # set new
self. F = f
What happens is that the call to super().__init__
creates a class with any a, b, c arguments you pass, a
self. E
and hard-coded “E0"
. After that, you execute the self. E =
e, then overwrite “E0"
with the value of the parameter e
.
Try this :
class SubC3(SuperC):
def __init__(self, a, b, c, f, d='new D', e='new E'):
super().__init__(a, b, c)
print("Before overwrite=%s" % self. E)
self. D = d # set new
self. E = e # set new
print("After overwrite=%s" % self. E)
self. F = f
sub3 = SubC3('A3', 'B3', 'C3', 'F3')
You will see that after initialization, you see the self. E
becomes “E0"
and then it is overridden:
Before overwrite=E0
After overwrite=new E
About d
:
Try this :
class SubC3(SuperC):
def __init__(self, a, b, c, f, d='new D', e='new E'):
super().__init__(a, b, c)
self. E = e # set new
self. F = f
sub3 = SubC3('A3', 'B3', 'C3', 'F3')
print(sub3. D)
You will see that it is D0 because you didn’t pass any d
to super and you didn’t override it in SubC3.__init__
, so it uses the default value in SuperC.__init__
where you do d='D0'
).