簡體   English   中英

如何初始化基(超級)類?

[英]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)

https://docs.python.org/3/library/functions.html#super

如何初始化基(超級)類?

 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 中不可變類型的子類的唯一方法。 因此,如果您想對strtuple或其他不可變對象進行子類化,則需要它。

你可能認為它是一個類方法,因為它有一個隱式的類參數。 但它實際上是一個靜態方法 所以你需要明確地用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM