簡體   English   中英

Python super()可選參數(以及super()的機制)

[英]Python super() optional arguments (and mechanics of super())

我有兩節課

class Something(object):
   def __init__(self):
      self.thing = "thing"

class SomethingElse(Something):
   def __init__(self):
      self.thing = "another"

如您所見,一個繼承自另一個。 當我運行super(SomethingElse) ,不會引發任何錯誤。 但是,當我運行super(SomethingElse).__init__() ,我期望的是未綁定的函數調用(未綁定到假設的SomethingElse實例),因此期望__init__()會抱怨沒有為其self參數接收對象,但是相反,我得到這個錯誤:

TypeError: super() takes at least 1 argument (0 given)

此消息是什么意思?

編輯:我經常看到人們揮手回答一個super問題,所以請不要回答,除非您真的知道super委托在這里是如何工作的,並且知道描述符以及如何將它們與super一起使用。

編輯:亞歷克斯建議我用更多詳細信息更新我的帖子。 我在3.6(Anaconda)中使用它的兩種方式都得到了一些不同。 不知道發生了什么。 我沒有收到亞歷克斯所做的事情,但得到了:

class Something(object):
   def __init__(self):
   self.thing = "thing"

class SomethingElse(Something):
   def __init__(self):
      super(SomethingElse).__init__()

調用(在Anaconda的3.6上):

SomethingElse()

<no problem>

super(SomethingElse).__init__()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: super(): no arguments 

super(SomethingElse).__init__(SomethingElse())

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: super() argument 1 must be type, not SomethingElse

我對super的理解是,根據https://docs.python.org/3/library/functions.html#super ,只有第一個參數的super()會使super對象不受實例限制,因此如果您在super對象上調用了__init__() ,則需要傳入一個實例,因為__init__()也是不受限制的。 但是,3.6抱怨使用super(SomethingElse).__init__(SomethingElse()SomethingElse不是一種type ,它應該是它從繼承自object的父代繼承而來的類型。

在2.7.13上給出了super(SomethingElse).__init__()的原始錯誤,它是TypeError: super() takes at least 1 argument (0 given) 對於super(SomethingElse).__init__(SomethingElse())會引發TypeError: super() argument 1 must be type, not SomethingElse

用1個參數調用super會生成一個“未綁定”的super對象。 這些很奇怪,沒有文檔記錄,而且幾乎沒有用,我將不討論它們的預期用途,但是出於這個答案的目的,我們真的只需要了解它們。

super(SomethingElse).__init__不會通過通常的super代理邏輯。 您將獲得super實例自己的__init__方法,而與SomethingElse沒有任何關系。

從那里開始,其余行為隨之而來。 在Python 2上, TypeError: super() takes at least 1 argument (0 given)是因為super.__init__至少接受1個參數,並且您將其傳遞為0。(您可能希望它說TypeError: super() takes at least 2 arguments (1 given)因為它仍在獲取self - super對象self ,而不是SomethingElse實例-但由於實現細節怪異,因此用C實現的方法通常不會將self計入此類錯誤消息。)

SomethingElse()在Python 3上成功,因為super構造函數從常規的堆棧檢查魔術中提取了__class__self

從類外部手動調用super(SomethingElse).__init__()會產生RuntimeError: super(): no arguments因為super.__init__試圖執行其堆棧檢查魔術,但未找到__class__self

super(SomethingElse).__init__(SomethingElse())失敗,因為super構造函數的第一個參數應該是類型,而不是實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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