views:

195

answers:

2

have this code

import threading
def Thread(f):
    def decorator(*args,**kargs):
        print(args) 
        thread = threading.Thread(target=f, args=args)
        thread.start()
        thread.join()
    decorator.__name__ = f.__name__
    return decorator      

@Thread
def add_item(a, b):
    return a+b


print(add_item(2,2))

but the function never return the value, exits a way to get the return ?

+2  A: 

That's because you never return a value in your "decorator"-function.

You have to include a shared variable in your thread and move the return value of your threaded function back into the "decorator"-function.

ebo
+4  A: 

The reason None is returned, is because there is nothing to return (besides the fact that decorator doesn't have a return statement). join() always returns None, as per the documentation.

For an example of how to communicate with a thread, see this email.

If I may ask though: since join() blocks the calling thread, what is there to gain here?


Edit: I played around a bit, and the following is a solution that doesn't require a queue (not saying it's a better solution. Just different):

import threading

# Callable that stores the result of calling the given callable f.
class ResultCatcher:
    def __init__(self, f):
        self.f = f
        self.val = None

    def __call__(self, *args, **kwargs):
        self.val = self.f(*args, **kwargs)

def threaded(f):
    def decorator(*args,**kargs):
        # Encapsulate f so that the return value can be extracted.
        retVal = ResultCatcher(f)

        th = threading.Thread(target=retVal, args=args)
        th.start()
        th.join()

        # Extract and return the result of executing f.
        return retVal.val

    decorator.__name__ = f.__name__
    return decorator

@threaded
def add_item(a, b):
    return a + b

print(add_item(2, 2))
Stephan202