我知道有两种从派生类调用超类构造函数的方法:super().__init__()
和base.__init__(self)
。为什么第二种方法需要我明确提供self
参数?
以下代码片段展示了其中的区别:
class base:
def __init__(self,/):
print("initializing")
class der(base):
def __init__(self):
super().__init__() #no error
base.__init__(self) #no error
base.__init__() #error, self required
obj = der()
第三次构造函数调用抛出此错误:
File "demo.py", line 11, in <module>
obj = der()
^^^^^
File "demo.py", line 9, in __init__
base.__init__() #error, should be: base.__init__(self)
^^^^^^^^^^^^^^^
TypeError: base.__init__() missing 1 required positional argument: 'self'
我希望base.__init__()
能够工作,因为super().__init__()
不需要明确的self
。
TL;DR:
super()
是一个实例。der
是一个类。为了正确理解这一点,你必须了解 Python 中实例方法的工作原理。编写实例方法时,必须
self
像下面这样包含第一个参数:这是因为当你调用一个实例方法时,Python 会自动将实例本身作为该方法的第一个参数。这两行代码的作用是一样的:
唯一的区别是第一行
bar
从实例调用,第二行bar
从类调用。在您的示例中,
base
是一个类(相当于Foo
),而不是一个实例(相当于x
)。因此,如果您想调用base
构造函数,则需要手动提供self
- Python 不会为您执行此操作。该
super
版本不需要这样做,因为super
不是类base
- 它是实例的代理self
,假装它是 类型der
而不是 类型base
。这意味着仍然super()
是一个实例,而不是类,因此super().__init__()
将自动self
作为参数提供base.__init__
,您无需手动执行此操作。