Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python class default value inheritance

I did some test 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 superclass, there are two types of default value (d and e) d is more 'open', while e is kind of '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 got good inheritance, and can accept new values. But I did not choose to have d and e in super().__init__(). BUT they got perfect inheritance as well, and the problem is that I can not change the value of d and e while creating the instance of the subclass. and f works fine.

Now I 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 written in both __init__() and super().__init__(), now that d can get perfect inheritance and can be overwritten with new default value or new value in an new instance. but e will still be E0

It seems like 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 that I can have both d and e with brand new default value/instance value, but if left non-indicated, then they will not inherit from the SuperC

My question is, am I thinking this the right way? Did I miss anything? Are there better ways to set default value inheritance?

Or maybe in a way, that e is not supposed to be changed if written in this way? because it could be a fundamental attribute that is supposed to be a constant value for both superclass and subclass?

like image 209
jxie0755 Avatar asked Jan 29 '26 17:01

jxie0755


1 Answers

I seem to fail the understand the issue...

When you do this:

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 hardcoded value: the string "E0" and d='D0' can be read as If you're called with an specific value in the d argument, use that one, otherwise, just use the string "D0" (it's a named optional argument)

When you do this:

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's happening is that the call to super().__init__ creates a class with whatever a, b, c arguments you passed, a self.E and the hardcoded "E0". After that, you do self.E = e and then you overwrite that "E0" with the value of the argument 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'll see that right after the init, you see self.E being "E0" and then it's overwritten:

Before overwrite=E0
After overwrite=new E

About the 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'll see that it's D0, because you didn't pass any d to the super and you didn't overwrite it in SubC3.__init__, so it used the default in the SuperC.__init__ (where you do d='D0')

like image 136
BorrajaX Avatar answered Jan 31 '26 06:01

BorrajaX