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