在继承Thread时调用超类构造函数

0 投票
1 回答
3895 浏览
提问于 2025-04-17 17:31

我很好奇,为什么在我的类继承自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 个回答

2

我很好奇,为什么我不能用 super(Thread, self).__init__() 来代替 Thread.__init__(self),当我的类继承自 Thread 时。

这是因为 super 的工作方式就是这样。你必须把你自己定义的类作为第一个参数传进去,这样它才能找到下一个继承的类。如果你传入 Thread,那就是在请求 Thread 的祖先类。

如果你的父类是一个普通的新式 Python 类,错误地使用这个方法通常意味着你会跳过一个祖先类,这可能没什么大不了,或者看起来能工作但实际上并没有做对事情。不过 threading.Thread 有特定的检查,确保它能正确初始化,所以你可能会遇到这样的情况:

AssertionError: Thread.__init__() was not called

如果你的父类是一个 C 扩展类,它可能没有任何祖先类,而且即使有,也可能不实现 super,所以你通常也会因此遇到错误。

如果你想了解这一切是如何运作的,建议你看看 Python 的 super() 详解(因为上面链接的文档不一定是最好的入门讨论)。

所以,总结一下:

super(Worker, self).__init__()

撰写回答