我正确使用 super() 吗?

发布于 2024-11-17 17:05:54 字数 542 浏览 3 评论 0原文

我编写了一小块代码,因为我仍在尝试找出使用 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()

I made a small chunk of code because I'm still trying to figure out the specifics of using super(). Why does this chunk run to this TypeError?

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

Then, the SecondClass.meth() function is supposed to print the string, but I'm clearly missing something conceptually.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

空‖城人不在 2024-11-24 17:05:54

这与 super 无关。您没有为 SecondClass 显式定义 __init__ - 但是,因为它继承自 FirstClass,所以它继承了 FirstClass__init__。因此,如果不传入 value 参数,就无法实例化该对象。

编辑确定。正如其他人所提到的,第一点是您必须始终在超级调用中使用当前类,而不是超类 - 在本例中是 super(SecondClass, self) 。那是因为 super 的意思是“获取类 x 的父级”,所以显然你的意思是“获取 SecondClass 的父级”——也就是 FirstClass。

第二点是在meth内部调用__init__方法是没有意义的。当您实例化对象时,__init__已经被调用。要么你的子类定义了自己的版本,可以选择是否调用自己的super方法;或者,如本例所示,它不会,在这种情况下会自动调用超类的版本。

让我重复一遍,因为我怀疑这是您理解中缺失的部分:子类化的全部要点是您没有专门重写的任何内容都会被继承。 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.

This isn't anything to do with super. You don't define an __init__ for SecondClass explicitly - but, because it inherits from FirstClass, it inherits FirstClass's __init__. So you can't instantiate the object without passing in the value parameter.

Edit OK. The first point, as others have mentioned, is that you must always use the current class in your super call, not the superclass - in this case super(SecondClass, self). That's because super means "get the parent of class x", so obviously you mean "get the parent of SecondClass" - which is FirstClass.

The second point is that it doesn't make sense to call the __init__ method inside meth. __init__ is already called when you instantiate the object. Either your subclass defines its own version, which can choose whether or not to call its own super method; or, as in this case, it doesn't, in which case the superclass's version is called automatically.

Let me repeat that, because I suspect that this is the missing piece in your understanding: the whole point of subclassing is that anything you don't specifically override, gets inherited anyway. super is only for those cases when you want to override something, but still use the logic from the super class as well.

So here's a silly example:

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.
情定在深秋 2024-11-24 17:05:54

SecondClass 的代码应该是这样的:

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

The code for SecondClass should be like this:

class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")
无所的.畏惧 2024-11-24 17:05:54

super() 的第一个参数应该是当前类,而不是父类:

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

Python 将找到将由其自身调用的实际函数。在本例中,它是父类,但当涉及多重继承时,情况可能并非如此。

The first argument of super() should be the current class, not the parent class:

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

Python will find the actual function that will be called by itself. In this case it's the parent class' but this may not be the case when multiple inheritance is involved.

合约呢 2024-11-24 17:05:54

应该是

super(SecondClass, self)

参见关于 super() 的 python 文档

It should be

super(SecondClass, self)

See the python documentation on super()

泡沫很甜 2024-11-24 17:05:54

修复 meth 函数

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

Fix meth function

class SecondClass (FirstClass):
    def meth (self):
        super (SecondClass,self).__init__(value = "I am a strange string")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文