![](/img/trans.png)
[英]How do I properly inherit from a base class using Super() (Python 2/3)?
[英]How do I initialize the base (super) class?
在 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 上搜索時,我找到了不止一種方法。 處理這個問題的標准方法是什么?
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
派生)。
兩個都
SuperClass.__init__(self, x)
或者
super(SubClass,self).__init__( x )
會起作用(我更喜歡第二個,因為它更符合 DRY 原則)。
請參閱此處: http : //docs.python.org/reference/datamodel.html#basic-customization
從 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)
如何初始化基(超級)類?
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
或其他不可變對象進行子類化,則需要它。
你可能認為它是一個類方法,因為它有一個隱式的類參數。 但它實際上是一個靜態方法。 所以你需要明確地用cls
調用__new__
。
我們通常從__new__
返回實例,因此如果您這樣做,您還需要在基類中通過super
調用基類的__new__
。 因此,如果您同時使用這兩種方法:
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')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.