当从线程继承时调用超类构造函数
问题描述:
我很好奇,为什么当我的类继承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()
答
我很好奇,为什么我不能叫
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__()
所有例子字母的类名,所以我糊涂了!谢谢你的回答! – 2013-03-01 02:01:33
@DavidM.Coe:这是一个很好的观点......它应该提醒我们其他人停止编写例子,其中A从B继承,反之亦然,并提出实际名称...... – abarnert 2013-03-01 02:10:41