Python3 中的简单线程

Simple Threading in Python3

在 Python2 中,我使用这种简单的方法 运行 通过 args 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 方法?

尝试如下:

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()

我以前发生过,在 child 上的任何尝试之前初始化 parent class,在这种情况下 FuncThread 最终被覆盖。

这是 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)

基础 threading.Thread class 使用 self._targetself._args 用于自己的目的。因为您在不带参数的情况下调用超级 __init__,所以它们在父构造函数中被设置为 None。要解决此问题,只需在创建实例时删除 __init__ use 关键字参数,并让默认行为为您完成工作:

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()

如果您想保留原始构造函数签名,则使用 targetargs 参数调用父 __init__,在这种情况下您不需要设置它们明确自己:

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()