与升级线程类和继承混淆

问题描述 投票:0回答:1

我试图理解如何子类化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

这允许我继承所有父类初始化属性,因为我正在使用*args, **kwargs,我可以在初始化程序中调用MyThread._target并且它可以工作。

但是,似乎我不需要调用super来修改run方法。我在网上看过这个例子:

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(),如果他们正在修改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()

OUTPUT:

<built-in function print>
test

Traceback:
custom.run()...........
print(self._target)
AttributeError: 'MyThread' object has no attribute '_target'[/python]

所以这些是我感到困惑的事情,我希望有人可以澄清这些细节。

谢谢。

python multithreading oop inheritance subclassing
1个回答
1
投票

调用Thread.__init__的例子不太常见。事实上,Thread.__init__确实采用了一些参数,但它们都有默认值,所以严格来说,你不必用任何参数调用它。

Thread.run必不可少,除了运行target选项传递给Thread.__init__的callable。如果你没有传递任何这样的论点,那么就没有必要打电话给Thread.run;重写的方法完成所有实际工作。

请注意,在使用super时,接受并传递未知参数非常重要,而不是因为您希望Thread方法获取任何必需的参数,而是因为您的类不知道接下来可能调用哪个类的方法。这是由self的运行时间决定的,而不是Thread的子类。

© www.soinside.com 2019 - 2024. All rights reserved.