为什么在类中需要Thread .__ init __()?

时间:2017-05-05 14:34:03

标签: python multithreading python-2.7

为什么在创建threading.Thread.__init__(self)课程时我被迫使用super(ClassName, self).__init__()threading.Thread

例如:

class Threader(threading.Thread):
    def __init__(self, _fp, _q):
        threading.Thread.__init__(self)
        self.path = _fp
        self.queue = _q

    def run(self):
        # Do stuff

class Threader(threading.Thread):
    def __init__(self, _fp, _q):
        super(Threader, self).__init__()
        self.path = _fp
        self.queue = _q

    def run(self):
        # Do stuff

这两种方法都有效,并且大致相同。但是,如果我删除.__init__()方法,我会在堆栈中收到:from thread.start(): thread.__init__() not called

不应该定义我自己的def __init__()“替换”.__init__()方法吗?

我已阅读this其他SO帖子并且与我的想法一致,但是会遇到相同的堆栈错误。

1 个答案:

答案 0 :(得分:3)

考虑这个简化的例子:

class dog:
    def __init__(self):
        self.legs = 4
        self.sound = 'woof'

class chihuahua(dog):
    def __init__(self):
        self.sound = 'yip'
        # what's missing here?

我们创建了dog的子类,名为chihuahua。这个类的用户会合理地期望它在所有默认方面都像狗一样,除了我们已经覆盖的特定一个(它产生的声音)。但请注意,正如您所指出的,新的子类__init__取代了基类__init__完全取代。与C ++不同,在创建子类实例时,基类初始化代码是 not 自动调用。因此,当您创建self.legs = 4时,行chihuahua()永远不会运行。结果,这种类型的狗跑来跑去,却不知道它有多少腿。因此,你可以说它不是一个功能齐全的狗,如果它在试图执行复杂的技巧时摔倒,你不应该感到惊讶。

作为子类设计者,您有两种方法可以解决此问题。第一种是在子类中显式重新实现self.legs = 4行。好吧,在这个例子中它可以正常工作,但它一般不是一个很好的选择,因为它违反了DRY原则,即使在你确切地知道要编写什么代码的情况下以及如何维护它。在更复杂的示例中(例如您的Thread子类),您可能赢得知道。第二个选项:显式调用超类初始值设定项并让它做它的事情。