Reputation: 16271
In Python2 I was using this simple way to run a Thread
an passing parameters via args:
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()
Now in Python3 this does not work anymore, and I'm getting
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
because in the run
override the self._args
are null. If I use the new syntax in Python3 it is
# this works fine in Python3
threading.Thread(target=testThreading, args=('Hello Thread!',)).start()
that works ok, so how to correctly override the run
method?
Upvotes: 1
Views: 959
Reputation: 4680
The base threading.Thread
class uses self._target
and self._args
for its own purposes. Because you are calling the super __init__
without arguments, those are being set to None
in the parent constructor. To fix this, simply remove your __init__
use keyword args when creating the instance, and let the default behavior do the job for you:
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()
If you want to keep your original constructor signature, then call the parent __init__
with the target
and args
arguments, in which case you don't need to set them explicitly yourself:
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()
Upvotes: 2
Reputation: 39354
This is a work-around for 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)
Upvotes: 1
Reputation: 9238
Try it as follows:
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()
It happened to me before, to init parent class before any attempt on the child, in this case FuncThread
ends up overriden.
Upvotes: 1