Путаница с подклассами потокового класса и наследования - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь понять, как создать подкласс потока, и меня смущают некоторые детали наследования. Кажется, если я хочу изменить __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 в инициализаторе, и это работает.

Однако, похоже, мне не нужно звонить в супер изменить метод запуска. Я видел этот пример онлайн:

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)

Здесь, кажется, они перезаписывают родительский init с помощью threading.Thread.__init__(self)? Тем не менее, threading.Thread.__init__(self) не вызывая любые параметры, так что это, по сути, пустой __init__ и не получает никаких родительских атрибутов, таких как target, args, group. Если я пытаюсь позвонить MyThread._target, я получаю сообщение об ошибке. Похоже, они создают совершенно новый init. Так зачем даже звонить threading.Thread.__init__, если вы не собираетесь наследовать атрибуты?

И почему метод run не требует вызова исходного threading.Thread.run(), если они модифицируют метод run? Кажется, только init требует вызова исходного init для модификации, но run не требует этого.

Теперь еще один аспект, который меня смутил, был, когда я пытался получить доступ к ._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]

Так что это то, что меня смущает, и я надеюсь, что кто-то сможет уточнить эти детали.

Спасибо.

1 Ответ

1 голос
/ 08 апреля 2019

Пример, который вызывает Thread.__init__, менее общий, чем мог бы быть.Thread.__init__ фактически принимает некоторые параметры, но все они имеют значения по умолчанию, поэтому, строго говоря, у вас нет для вызова с любыми аргументами.

Thread.runessential ничего не делает, кроме запуска вызываемой функции, переданной в качестве опции target в Thread.__init__.Если вы не передадите такой аргумент, вам не нужно будет вызывать Thread.run;переопределенный метод выполняет всю реальную работу.

Обратите внимание, что при использовании super важно принимать и передавать неизвестные аргументы, не так много, потому что вы хотите, чтобы методы Thread получали любые требуемые аргументы,но поскольку ваш класс не знает , какой метод класса может быть вызван следующим.Это определяется временем выполнения self, а не подклассом Thread.

...