在Python中,请考虑我有以下代码:
>>> class SuperClass(object):
def __init__(self, x):
self.x = x
>>> class SubClass(SuperClass):
def __init__(self, y):
self.y = y
# how do I initialize the SuperClass __init__ here?
如何初始化子类中的SuperClass __init__
?我正在关注Python教程,但它没有涵盖这一点。当我在Google上搜索时,我找到了不止一种方法。处理此问题的标准方法是什么?
答案 0 :(得分:130)
Python(直到版本3)支持“旧式”和新式类。新式类派生自object
并且正在使用,并通过super()
调用其基类,例如。
class X(object):
def __init__(self, x):
pass
def doit(self, bar):
pass
class Y(X):
def __init__(self):
super(Y, self).__init__(123)
def doit(self, foo):
return super(Y, self).doit(foo)
因为python知道旧式和新式类,所以有不同的方法来调用基本方法,这就是为什么你找到了多种方法。
为了完整起见,旧式类使用基类显式调用基本方法,即
def doit(self, foo):
return X.doit(self, foo)
但是既然你不应该再使用旧式了,我就不会太在意了。
Python 3只知道新式类(无论你是否派生自object
)。
答案 1 :(得分:34)
两个
SuperClass.__init__(self, x)
或
super(SubClass,self).__init__( x )
会起作用(我更喜欢第二个,因为它更符合DRY原则)。
见这里:http://docs.python.org/reference/datamodel.html#basic-customization
答案 2 :(得分:15)
如何初始化基础(超级)类?
class SuperClass(object): def __init__(self, x): self.x = x class SubClass(SuperClass): def __init__(self, y): self.y = y
使用super
对象确保您在方法解析顺序中获得下一个方法(作为绑定方法)。在Python 2中,您需要将类名称和self
传递给super以查找绑定的__init__
方法:
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
在Python 3中,有一些神奇的东西会使super
的参数变得不必要 - 而且作为一个附带好处,它可以更快地运行:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
如下所示对父级进行硬编码会阻止您使用协作多重继承:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
请注意__init__
may only return None
- 它旨在就地修改对象。
__new__
还有另一种初始化实例的方法 - 它是Python中不可变类型的子类的唯一方法。因此,如果您想要继承str
或tuple
或其他不可变对象,则需要它。
您可能认为它是一种类方法,因为它获得了一个隐式类参数。但它是actually a staticmethod。因此,您需要明确地使用__new__
致电cls
。
我们通常会从__new__
返回实例,因此如果您这样做,您还需要在基类中通过__new__
调用基础super
。因此,如果您使用这两种方法:
class SuperClass(object):
def __new__(cls, x):
return super(SuperClass, cls).__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super(SubClass, cls).__new__(cls)
def __init__(self, y):
self.y = y
super(SubClass, self).__init__('x')
Python 3避开了__new__
作为静态方法导致的超级调用的一些奇怪现象,但您仍然需要将cls
传递给非绑定__new__
方法:
class SuperClass(object):
def __new__(cls, x):
return super().__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super().__new__(cls)
def __init__(self, y):
self.y = y
super().__init__('x')
答案 3 :(得分:14)
从python 3.5.2开始,您可以使用:
class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)