我试图了解如何对Thread进行子类化,
而且我对继承的一些细节感到困惑。
好像我要修改
__init__
我需要按以下方式调用super:
class MyThread(threading.Thread):
def __init__(self, url, browser, *args, **kwargs):
super(MyThread, self).__init__(*args, **kwargs)
self.url = url
self.browser = browser
这使我可以继承所有父母init
属性,就像我正在使用*args, **kwargs
一样,我可以在初始化器中调用MyThread._target
,并且可以正常工作。
但是,我似乎不需要调用super来 修改运行方法。我在网上看到了这个例子:
class MyThread(threading.Thread):
def __init__(self, number, logger):
threading.Thread.__init__(self)
self.number = number
self.logger = logger
def run(self):
"""
Run the thread
"""
#modification to run method but no call to it
logger.debug('Calling doubler')
doubler(self.number, self.logger)
在这里似乎他们正在用threading.Thread.__init__(self
覆盖父init?
但是,threading.Thread.__init__(self)
不是
调用任何参数,因此它本质上是一个空__init__
,并且不会获取任何父属性,例如target,args,group。如果我尝试致电MyThread._target
,则会收到错误消息。
因此,似乎他们正在创建全新的init
。那么,如果您不继承任何内容,为什么还要致电threading.Thread.__init__
属性?
如果运行方法正在修改运行方法,为什么不要求调用原始threading.Thread.run()
?
似乎只有init才需要调用原始init进行修改,但run并不需要。
现在让我感到困惑的另一个方面是,当我尝试在超级继承之后访问._target
时;在run方法中找不到该属性:
class MyThread(threading.Thread):
def __init__(self, number, style, *args, **kwargs):
super().__init__(*args, **kwargs)
self.number = number
self.style = style
print(self._target) # works here
def run(self, *args, **kwargs):
super().run(*args, **kwargs)
print(self._target) # leads to error
print('thread has ended')
custom = MyThread(target = print, number = 3, style ="red", args = ("test",))
custom.run()
输出:
<built-in function print>
test
Traceback:
custom.run()...........
print(self._target)
AttributeError: 'MyThread' object has no attribute '_target'[/python]
这些就是我很困惑的事情,希望有人能澄清这些细节。
谢谢。
答案 0 :(得分:1)
调用Thread.__init__
的示例不那么通用。 Thread.__init__
实际上有一些参数,但是它们都有默认值,因此严格来说,您没有拥有可以使用任何参数来调用它。
Thread.run
必需的内容什么都不做,除了运行通过target
选项传递给Thread.__init__
的可调用对象。如果您不传递任何此类参数,则无需真正调用Thread.run
;覆盖的方法可以完成所有实际工作。
请注意,在使用super
时,接受并传递未知参数很重要,不是那么重要,因为您希望Thread
方法获取任何必需的参数,但因为您的类不会< em>知道下一步将调用什么类的方法。这取决于self
的运行时间,而不是Thread
的子类。