I am trying to run some instance methods as background threads using a decorator. Several nested functions are chained (as found there) to make it work:
import traceback
from functools import partial
from threading import Thread
def backgroundThread(name=''):
def fnWrapper(decorated_func):
def argsWrapper(name, *inner_args, **inner_kwargs):
def exceptionWrapper(fn, *args, **kwargs):
try:
fn(*args, **kwargs)
except:
traceback.print_exc()
if not name:
name = decorated_func.__name__
th = Thread(
name=name,
target=exceptionWrapper,
args=(decorated_func, ) + inner_args,
kwargs=inner_kwargs
)
th.start()
return partial(argsWrapper, name)
return fnWrapper
class X:
@backgroundThread()
def myfun(self, *args, **kwargs):
print(args, kwargs)
print("myfun was called")
#1 / 0
x = X()
x.myfun(1, 2, foo="bar")
x.myfun()
Output/Error (on Windows, Python 3.6.6):
(2,) {'foo': 'bar'}
myfun was called
Traceback (most recent call last):
File "t3.py", line 11, in exceptionWrapper
fn(*args, **kwargs)
TypeError: myfun() missing 1 required positional argument: 'self'
The code works partly, how to be able to 'bind' self to the call: x.myfun() which takes no arguments ?