Простые потоки в Python3 - PullRequest
       33

Простые потоки в Python3

0 голосов
/ 28 февраля 2019

В Python2 я использовал этот простой способ для запуска Thread передачи параметров через аргументы:

import threading


class FuncThread(threading.Thread):
    '''
        it worked fine in Python2
    '''
    def __init__(self, target, *args):
        self._target = target
        self._args = args
        print( self._args )
        threading.Thread.__init__(self)
    def run(self, *args):
      print( self._args )
      self._target(*self._args)

def testThreading(say=''):
  print("I'm a thread %s" % say)

t = FuncThread(testThreading, 'hi')
t.start()

Теперь в Python3 это больше не работает, и я получаю

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "main.py", line 11, in run
    self._target(*self._args)
TypeError: 'NoneType' object is not callable

, потому что в переопределении run self._args равны нулю.Если я использую новый синтаксис в Python3, это

# this works fine in Python3
threading.Thread(target=testThreading, args=('Hello Thread!',)).start()

, который работает нормально, так как правильно переопределить метод run?

Ответы [ 3 ]

0 голосов
/ 28 февраля 2019

Это обходной путь для Python3:

class FuncThread(threading.Thread):
    def __init__(self, target, *args):
        self._xtarget = target
        self._args = args
        print( self._args )
        threading.Thread.__init__(self)
    def run(self, *args):
      print( self._args )
      self._xtarget(*self._args)
0 голосов
/ 28 февраля 2019

Базовый класс threading.Thread использует self._target и self._args для своих собственных целей.Поскольку вы вызываете супер __init__ без аргументов, они устанавливаются в None в родительском конструкторе.Чтобы это исправить, просто удалите свои __init__ аргументы ключевых слов при создании экземпляра и позвольте поведению по умолчанию выполнить работу за вас:

import threading

class FuncThread(threading.Thread):
    def run(self, *args):
      print( self._args )
      self._target(*self._args)

def testThreading(say=''):
  print("I'm a thread %s" % say)

t = FuncThread(target=testThreading, args=('hi',))
t.start()

Если вы хотите сохранить свою оригинальную подпись конструктора, затем вызовитеродительский __init__ с аргументами target и args, в этом случае вам не нужно задавать их самостоятельно:

import threading

class FuncThread(threading.Thread):
    def __init__(self, target, *args):
        super().__init__(target=target, args=args)
    def run(self, *args):
      print( self._args )
      self._target(*self._args)

def testThreading(say=''):
  print("I'm a thread %s" % say)

t = FuncThread(testThreading, 'hi')
t.start()
0 голосов
/ 28 февраля 2019

Попробуй это следующим образом:

import threading


class FuncThread(threading.Thread):

    def __init__(self, target, *args):
      threading.Thread.__init__(self)
      self._target = target
      self._args = args
      print( self._args )

    def run(self, *args):
      print( self._args )
      self._target(*self._args)

def testThreading(say=''):
  print("I'm a thread %s" % say)

t = FuncThread(testThreading, 'hi')
t.start()

Раньше мне приходилось инициировать родительский класс до любой попытки на ребенка, в этом случае FuncThread заканчивается переопределением.

...