混淆子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.