【问题标题】:Python: Calling the __init__() method of a base class using super() when it requires arguments [duplicate]Python:在需要参数时使用 super() 调用基类的 __init__() 方法[重复]
【发布时间】:2025-12-19 14:05:07
【问题描述】:

我试图在超类中调用__init__() 方法,其中所述方法接受参数,但它似乎不起作用。请看下面的代码:

>>> class A:
        def __init__(self, param1, param2):
            self._var1 = param1
            self._var2 = param2

>>> class B(A):
        def __init__(self, param1, param2, param3):
            super(B, self).__init__(param1, param2)
            self._var3 = param3


>>> a = A("Hi", "Bob")
>>> a._var1
'Hi'
>>> a._var2
'Bob'
>>> 
>>> b = B("Hello", "There", "Bob")

Traceback (most recent call last):
  File "<pyshell#74>", line 1, in <module>
    b = B("Hello", "There", "Bob")
  File "<pyshell#69>", line 3, in __init__
    super(B, self).__init__(param1, param2)
TypeError: must be type, not classobj
>>>

我从来没有让这个工作。我究竟做错了什么?理想情况下,我希望使用super() 而不是A.__init__(self, &lt;parameters&gt;),如果这是可能的(它必须是)。

【问题讨论】:

    标签: python inheritance super


    【解决方案1】:

    根据经验:在 Python 2 中,您的基类应始终从 object 继承,否则您使用的旧样式类具有您所描述的令人惊讶的行为。

    所以试试

    class A(object):
        ...
    

    像这样:

    In [1]: class A(object):
       ...:     def __init__(self, param1, param2):
       ...:         self._var1 = param1
       ...:         self._var2 = param2
       ...:
    
    In [2]: class B(A):
       ...:     def __init__(self, param1, param2, param3):
       ...:         super(B, self).__init__(param1, param2)
       ...:         self._var3 = param3
       ...:
    
    In [3]: a = A("Hi", "Bob")
    
    In [4]: a._var1
    Out[4]: 'Hi'
    
    In [5]: a._var2
    Out[5]: 'Bob'
    
    In [6]: b = B("Hello", "There", "Bob")
    
    In [7]: b._var3
    Out[7]: 'Bob'
    

    如果你真的知道你在做什么(至少见the docsthis)并且你想使用旧式类你不能使用super(),而是需要手动调用super -class 的__init__ 来自子类,如下所示:

    class A:
        ...
    
    class B(A):
        def __init__(self, p1, p2, p3):
            A.__init__(p1, p2)
            ...
    

    【讨论】:

    • 没有“如果”; Python 3 没有 classobj 类型。
    • 现在可以使用了。谢谢!
    【解决方案2】:

    您仍然可以使用旧样式类,但在这种情况下,应显式调用基类 __init__ 方法:

    class A:
        def __init__(self, param1, param2):
            self._var1 = param1
            self._var2 = param2
    
    class B(A):
        def __init__(self, param1, param2, param3):
            A.__init__(self, param1, param2)
            self._var3 = param3
    

    测试:

    >>> b = B("Hello", "There", "Bob")
    >>> b._var1
    'Hello'
    >>> b._var2
    'There'
    >>> b._var3
    'Bob'
    >>>
    

    【讨论】:

    • 一般来说,你不应该再在新代码中编写旧式类了,但是知道这一点很好,因为即使在标准库中,仍然有旧式类的实例。
    【解决方案3】:

    解决方法是在声明 A 时引用对象类

    class A(object):
        def __init__(self, param1, param2):
            self._var1 = param1
            self._var2 = param2
    

    这允许脚本成功执行。

    【讨论】:

      最近更新 更多