2013-03-01 101 views
0

我很好奇,爲什麼當我的類繼承Thread時,我不能調用super(Thread, self).__init__()而不是Thread.__init__(self)。你能幫我理解這個問題嗎?當從線程繼承時調用超類構造函數

#!/usr/bin/python 

from threading import Thread 
from Queue import Queue 
class ThreadManager(object): 

    def work(self, items): 
     q = Queue() 
     for item in items: 
      q.put(item) 

     print q.qsize() 

     p = Worker() 
     p.start() 
     p.join() 

class Worker(Thread): 
    def __init__(self): 
     # Why doesn't this work? 
     #super(Thread, self).__init__() 

     Thread.__init__(self) 

    def run(self): 
     print 'thread running' 

def main(): 
    items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] 
    tm = ThreadManager() 
    tm.work(items) 

if __name__ == "__main__": 
    main() 

回答

1

我很好奇,爲什麼我不能叫super(Thread, self).__init__()而不是Thread.__init__(self)當我的類從Thread繼承。

因爲那不是super如何工作。您必須將您的自己的類型作爲第一個參數,以便它可以搜索該類型的下一個祖先。如果你通過它Thread,你要求一個Thread的祖先。

如果你的父類是有規律的新型Python類,這樣做不對通常意味着你跳過一個祖先類,這可能是無害的,也可能似乎工作,但實際上沒有做正確的事。但threading.Thread有具體的檢查,以確保它得到正確的初始化,所以你可能會得到這樣的事情:

AssertionError: Thread.__init__() was not called 

如果你的父類是C擴展級,它可能沒有任何祖,它可能不會實現super即使它,所以你通常會得到一個這樣的錯誤。

如果您想了解所有這些工作方式(因爲上面鏈接的文檔不一定是最好的介紹性討論),您可能需要閱讀Python's super() considered super

因此,簡言之:我用用

super(Worker, self).__init__() 
+0

所有例子字母的類名,所以我糊塗了!謝謝你的回答! – 2013-03-01 02:01:33

+0

@DavidM.Coe:這是一個很好的觀點......它應該提醒我們其他人停止編寫例子,其中A從B繼承,反之亦然,並提出實際名稱...... – abarnert 2013-03-01 02:10:41