python类默认值继承

时间:2017-12-31 01:58:35

标签: python oop inheritance

我今天做了一些测试:

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

你可以在超类中看到,有两种类型的默认值(ded更开放,而e有点隐藏'

现在,如果我创建一个子类,使用新属性' 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   

我可以看到abc获得了良好的继承,并且可以接受新值。 但我没有在d选择esuper().__init__()。但是它们也有完美的继承,问题是我在创建子类的实例时无法更改de的值。 f工作正常。

现在我创建了另一个子类:

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

d__init__()中都写有super().__init__(),现在d可以获得完美的继承,并且可以在新实例中使用新的默认值或新值覆盖。但是e仍然是E0

似乎唯一的好方法是:

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

既然我可以同时使用全新的默认值/实例值de,但如果不显示,那么它们将不会从SuperC继承

我的问题是,我认为这是正确的方法吗? 我错过了什么吗? 有没有更好的方法来设置默认值继承?

或者在某种程度上,如果以这种方式编写,e不应该被更改?因为它可能是一个基本属性,应该是超类和子类的常量值?

1 个答案:

答案 0 :(得分:1)

我似乎无法理解这个问题......

执行此操作时:

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不是“隐藏”的。它刚刚收到一个硬编码值:字符串"E0"d='D0'可以读作如果在d参数中使用特定值调用,请使用该值,否则,只需使用字符串"D0" (它是named optional argument

执行此操作时:

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

正在发生的事情是,对super().__init__的调用会创建一个类,其中包含您传递的a, b, c个参数,self.E和硬编码的"E0"。之后,执行self.E = e,然后使用参数"E0"的值覆盖e

试试这个:

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')

您会在初始化后看到self.E"E0"然后被覆盖:

Before overwrite=E0
After overwrite=new E

关于d

试试这个:

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)

你会看到它是D0,因为你没有将任何d传递给超级,而你没有在SubC3.__init__中覆盖它,所以它使用了默认值SuperC.__init__(你在哪里d='D0'