我是否正确使用了super()?

7

我写了一小段代码,因为我仍在尝试弄清楚如何使用super()的细节。为什么这段代码会出现TypeError错误?

 a = SecondClass()
TypeError: __init__() takes exactly 2 arguments (1 given)

然后,SecondClass.meth()函数应该打印字符串,但显然我在概念上漏掉了什么。

class FirstClass (object):
    def __init__ (self, value):
        self.value = value
        print self.value

class SecondClass (FirstClass):
    def meth (self):
        super (FirstClass,self).__init__(value = "I am a strange string")

a = SecondClass()
a.meth()

3
从子类方法调用超类构造函数是一个有趣的想法。 - Fred Foo
5个回答

8

这与super无关。你没有为SecondClass显式定义一个__init__,但是因为它继承自FirstClass,所以它继承了FirstClass__init__。因此,你不能在不传递value参数的情况下实例化该对象。

编辑:好的。正如其他人提到的那样,第一点是你必须始终在super调用中使用当前类,而不是超类——在这种情况下是super(SecondClass, self)。这是因为super意味着“获取类x的父类”,所以显然你想要“获取SecondClass的父类”——即FirstClass。

第二点是在meth内调用__init__方法没有意义。__init__已经在实例化对象时被调用。你的子类可以定义自己的版本,并选择是否调用自己的超类方法;或者像这个例子一样,不定义,这样就会自动调用超类的版本。

我想重申一下,因为我怀疑这是你理解中缺失的部分:子类化的整个意义在于,任何你没有明确覆盖的东西都会被继承。只有在你想要覆盖某些内容但仍然使用超类逻辑的情况下,super才有用。

因此,这是一个愚蠢的例子:

class FirstClass(object):
    def __init__ (self, value="I am the value from FirstClass"):
        print value

    def meth(self):
        print "I am meth from FirstClass"

    def meth2(self):
        print "I am meth2 from FirstClass"

class SecondClass(FirstClass):
    def __init__ (self):
        print "I am in SecondClass"
        super(SecondClass, self).__init__(value="I am the value from SecondClass")

    def meth(self):
        print "I am meth from SecondClass"


a=FirstClass() # prints "I am the value from FirstClass"
b=SecondClass() # prints *both* "I am in SecondClass" *and* "I am the value from SecondClass

a.meth() # prints "I am meth from FirstClass"
b.meth() # prints "I am meth from SecondClass"

a.meth2() # prints "I am meth2 from FirstClass"
b.meth2() # *also* prints "I am meth2 from FirstClass", because you didn't redefine it.

谢谢...您能提供一个使用super从第二个类调用的简单示例吗? - Louis93
明白了。很好的例子,很好的解释。终于恍然大悟了。 - Louis93

3
第二类的代码应该是这样的:
class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")

2
super()的第一个参数应该是当前类,而不是父类:
class SecondClass(FirstClass):
    def meth(self):
        super(SecondClass, self).__init__(value="I am a strange string")

Python会自动查找实际调用的函数。在这种情况下,它是父类的函数,但当涉及多重继承时可能不是这种情况。


1
修复meth函数
class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接