为什么我在创建线程时被迫使用
类?threading.Thread.__init__(self)
或super(ClassName, self).__init__()
.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 帖子与我的想法一致,但得到相同的堆栈错误。
最佳答案
考虑这个简化的示例:
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++ 不同,创建子类实例时不会自动调用基类初始化代码。因此,当您创建 chihuahua()
时,self.legs = 4
行永远不会运行。结果,这种狗到处乱跑,根本不知道自己有多少条腿。因此,你可能会说它不是一只功能齐全的狗,如果它在尝试执行复杂技巧时摔倒,你也不应该感到惊讶。
作为子类设计者,您有两种选择来解决此问题。第一个是在子类中显式重新实现 self.legs = 4
行。好吧,这在这个例子中可以很好地工作,但一般来说这不是一个很好的选择,因为它违反了 DRY 原则,即使您确实知道要编写什么代码以及如何维护它。在更复杂的示例中(例如您的 Thread 子类),您可能不会知道。第二个选项:显式调用父类(super class)初始值设定项并让它执行其操作。
关于python - 为什么类中需要 Thread.__init__() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43807642/