混淆子class线程class和继承
Confusion with subclassing a threading class, and inheritance
我正在尝试了解如何将线程子类化,
我对继承的一些细节感到困惑。
好像要修改
__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
这让我可以继承所有的父初始化
属性,因为我正在使用 *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
) 覆盖了父初始化?
但是,threading.Thread.__init__(self)
不是
调用任何参数,因此它本质上是一个空 __init__
并且不获取任何父属性,例如目标、参数、组。如果我尝试调用 MyThread._target
,我会收到错误消息。
所以看起来他们正在创建一个全新的 init
。那么,如果您不打算继承任何东西,为什么还要调用 threading.Thread.__init__
属性?
如果他们正在修改 运行 方法,为什么 运行 方法不需要调用原始 threading.Thread.run()
?
似乎只有 init 需要调用原始 init 进行修改,但 运行 不需要这样。
现在我感到困惑的另一个方面是,当我试图在超级继承之后访问 ._target
时;在 运行 方法中找不到属性:
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]
调用 Thread.__init__
的示例不如它应有的一般。 Thread.__init__
事实上,确实有一些参数,但它们都有默认值,所以严格来说,你 没有 可以用任何参数调用它。
Thread.run
essential 除了 运行 作为 target
选项传递给 Thread.__init__
的可调用对象外什么都不做。如果你不传递任何这样的参数,就没有真正需要调用 Thread.run
;覆盖的方法完成所有实际工作。
请注意,在使用 super
时,接受并传递未知参数很重要,这与其说是因为您希望 Thread
方法获取任何必需的参数,不如说是因为您的 class 不知道 class 接下来可能调用什么方法。那是由self
的运行time时间决定的,不是Thread
的subclass.
我正在尝试了解如何将线程子类化,
我对继承的一些细节感到困惑。
好像要修改
__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
这让我可以继承所有的父初始化
属性,因为我正在使用 *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
) 覆盖了父初始化?
但是,threading.Thread.__init__(self)
不是
调用任何参数,因此它本质上是一个空 __init__
并且不获取任何父属性,例如目标、参数、组。如果我尝试调用 MyThread._target
,我会收到错误消息。
所以看起来他们正在创建一个全新的 init
。那么,如果您不打算继承任何东西,为什么还要调用 threading.Thread.__init__
属性?
如果他们正在修改 运行 方法,为什么 运行 方法不需要调用原始 threading.Thread.run()
?
似乎只有 init 需要调用原始 init 进行修改,但 运行 不需要这样。
现在我感到困惑的另一个方面是,当我试图在超级继承之后访问 ._target
时;在 运行 方法中找不到属性:
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]
调用 Thread.__init__
的示例不如它应有的一般。 Thread.__init__
事实上,确实有一些参数,但它们都有默认值,所以严格来说,你 没有 可以用任何参数调用它。
Thread.run
essential 除了 运行 作为 target
选项传递给 Thread.__init__
的可调用对象外什么都不做。如果你不传递任何这样的参数,就没有真正需要调用 Thread.run
;覆盖的方法完成所有实际工作。
请注意,在使用 super
时,接受并传递未知参数很重要,这与其说是因为您希望 Thread
方法获取任何必需的参数,不如说是因为您的 class 不知道 class 接下来可能调用什么方法。那是由self
的运行time时间决定的,不是Thread
的subclass.