问题:如何初始化基类(超级)?
在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
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
都
SuperClass.__init__(self, x)
要么
super(SubClass,self).__init__( x )
会起作用(我更喜欢第二个,因为它更加遵守DRY原则)。
参见此处:http : //docs.python.org/reference/datamodel.html#basic-customization
回答 2
从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)
回答 3
如何初始化基类(超级)?
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__
可能仅返回None
-它旨在就地修改对象。
东西 __new__
还有另一种初始化实例的方法-这是Python中不可变类型的子类的唯一方法。所以,如果你想子类它需要str
或tuple
或其他不可变对象。
您可能会认为这是一个类方法,因为它获得了隐式类参数。但这实际上是一种静态方法。所以,你需要打电话__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')