代码之家  ›  专栏  ›  技术社区  ›  James Wang

为什么我的超类要调用我的子类方法?

  •  4
  • James Wang  · 技术社区  · 8 年前

    当我调用从构造函数重写的方法时,我得到一个错误,它说它缺少一个参数(由于子类需要第二个参数)。但是,我在super()中调用了该方法,那么为什么它不调用该方法的超类版本呢?

    这可以用一个简短的例子来最好地说明:

    class A:
        def __init__(self):
            self.do()
    
        def do(self):
            print("A")
    
    
    class B(A):
        def __init__(self):
            super().__init__()
            self.do("B")
    
        def do(self, arg2):
            super().do()
            print(arg2)
    
    
    b = B()
    

    以下是我得到的错误:

    Traceback (most recent call last):
        File "D:/Python/Advanced/randomStuff/supersub.py", line 19, in <module>
            b = B()
        File "D:/Python/Advanced/randomStuff/supersub.py", line 11, in __init__
            super().__init__()
        File "D:/Python/Advanced/randomStuff/supersub.py", line 3, in __init__
            self.do()
    TypeError: do() missing 1 required positional argument: 'arg2'
    

    它似乎在调用类B中的do()方法,但我想调用类A中的do()方法。 理想情况下,代码应打印:

    A
    A
    B
    

    我做错了什么?

    2 回复  |  直到 8 年前
        1
  •  3
  •   see sharper    8 年前

    答案是,如果基类调用的方法是在其自身上定义的,但也被子类重写,则调用 子类上的重写方法 不是基类上的方法。有关更多信息,请参阅 calling an overridden method from base class? 。请参阅下面的代码变体,并遵循上述逻辑。

    class A:
        def __init__(self):
            self.do()
    
        def do(self):
            print("do A")
    
    
    class B(A):
        def __init__(self):
            super().__init__()
            self.do()
    
        def do(self):
            super().do()
            print("do B")
    
    
    b = B()
    

    结果: A. B A. B

        2
  •  0
  •   Patrick Rutz    8 年前

    这真的很奇怪。我没有一个解决方案,但下面的方法似乎按预期的方式工作。它完全相同,只是super()是用self显式调用的。 作为一个论点,我认为这是含蓄的。

    也许一个更熟练的蟒蛇可以在这个观察的基础上发展。

    class A:
        def __init__(self):
            self.do()
    
        def do(self):
            print("A")
    
    class B(A):
        def __init__(self):
            super(self.__class__).__init__()
            self.do("B")
    
        def do(self, arg2):
            super().do()
            print(arg2)
    
    print('***init A***')
    a = A()
    print('***init B***')
    b = B()
    print('***A.do()***')
    a.do()
    print('***B.do()***')
    b.do('test')