I have built a simple decorator that tracks if the function has been run or not.
import functools
from multiprocessing import Process, Queue
def counter_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
if not wrapper.has_run:
output = f(*args, **kwargs)
wrapper.has_run = True
return output
wrapper.has_run = False
return wrapper
If I decorate a class function with this decorator it works perfectly, but if I pass it to the multiprocessing Queue then for some reason the flag is set to False:
class A:
@counter_decorator
def foo(self):
pass
def worker(queue):
a = A()
a.foo()
assert a.foo.has_run
queue.put(a)
queue = Queue()
p = Process(target=worker, args=(queue,))
p.start()
res = queue.get()
p.join()
assert res.foo.has_run, 'This is unexpected'
I do not understand why this is happening and what can I do to make it work ? I have read this thread which mentions decorated functions pickeling issues: Python decorator with multiprocessing fails
But I am not quite sure how pickeling is related here as the below example works fine:
import pickle
a = A()
a.foo()
pickled = pickle.dumps(a)
assert pickle.loads(pickled).foo.has_run