1

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
Kreol
  • 207
  • 2
  • 7

0 Answers0