什么时候超级(Baseclass,self).__ init__使用

kar*_*t18 3 python class super

何时应该在Python中使用以下代码(假设Baseclass继承自Parent类,而Parent类在__init __()方法中启动了一些变量)

class Baseclass(Parent):
    def __init__(self, some_arg):
        self.some_arg = some_arg
        super(Baseclass, self).__init__()
Run Code Online (Sandbox Code Playgroud)

此代码是否使在Parentclass的__init__方法中定义的所有局部变量都可以在Baseclass中访问?它有什么意义?

小智 6

super防止代码重复; 复杂的__init__不需要进入你的继承类.它还使MRO正常工作,这样如果你使用多重继承,它将正常工作.

这样做的一个原因是确保所有继承对象都具有父级没有的某些属性.如果你只是写一个新的__init__,除非你重复你的代码,否则他们不会有它们.例如:

>>> class A(object):
...     def __init__(self, x):
...             self.x = x
... 
>>> class B(A):
...     def __init__(self, y):
...             self.y = y
... 
>>> Stick = B(15)
>>> Stick.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute 'x'
>>>
Run Code Online (Sandbox Code Playgroud)

在没有调用super期间,__init__只需覆盖整个方法.对super此处的调用可确保继承的类中存在这两个变量.

>>> class C(A):
...     def __init__(self, x, y):
...             super(C, self).__init__(x)
...             self.y = y
... 
>>> Dave = C(15, 22)
>>> Dave.x
15
>>> Dave.y
22
>>>  
Run Code Online (Sandbox Code Playgroud)

请注意,在super调用中,x传递给__init__()调用,但在代码selfsuper(C, self)一部分中处理.

编辑:TyrantWave也正确地指出,除此之外也是super非常有用的__init__.foo例如,使用简单的方法获取对象.

class Parent(object):
    def foo(self):
        return "I say foo!"
Run Code Online (Sandbox Code Playgroud)

继承的类可能只想改变此函数的输出而不是完全重写它.因此,我们不是重复自己并重复编写相同的代码,而是调用super获取父级的返回值,然后处理数据并返回子类的修改结果.

class Child(Parent):
    def foo(self):
        parent_result = super(Child, self).foo()
        return "I'm a child!! %s" % parent_result
Run Code Online (Sandbox Code Playgroud)

在上面,调用super返回Parents值foo(),然后Child在返回数据之前继续处理数据.

>>> Alan = Parent()
>>> Stan = Child()
>>> Alan.foo()
'I say foo!'
>>> Stan.foo()
"I'm a child!! I say foo!"
>>> 
Run Code Online (Sandbox Code Playgroud)