关于继承:Python:当需要参数时,使用super()调用基类的__init __()方法

Python: Calling the __init__() method of a base class using super() when it requires arguments

本问题已经有最佳答案,请猛点这里访问。

我试图在一个超类中调用__init__()方法,该方法接受参数,但似乎不起作用。请参见下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> 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, )


经验法则:在python 2中,您的基类应该总是从object继承,否则您使用的是具有令人惊讶的行为的旧式类,就像您描述的那样。

所以尝试

1
2
class A(object):
    ...

这样地:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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'

如果你真的知道你在做什么(至少看到文档和这个),并且你想使用旧样式的类,你不能使用super(),而是需要从这样的子类手动调用超级类的__init__

1
2
3
4
5
6
7
class A:
    ...

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


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

1
2
3
4
5
6
7
8
9
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

测试:

1
2
3
4
5
6
7
8
>>> b = B("Hello","There","Bob")
>>> b._var1
'Hello'
>>> b._var2
'There'
>>> b._var3
'Bob'
>>>


修复方法是在声明

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

这允许脚本成功执行。