# how to get the return value from a thread in python?

How can I access that return value 'foo' from the thread?

def foo(bar):
print 'hello {0}'.format(bar)
return 'foo'

t.start()
x = t.join()
print x

The one obvious way to do it, above, seems to just return None in x.

-

FWIW, the multiprocessing module has a nice interface for this using the Pool class. And if you want to stick with threads rather than processes, you can just use themultiprocessing.pool.ThreadPool class as a drop-in replacement.

def foo(bar, baz):
print 'hello {0}'.format(bar)
return 'foo' + baz

async_result = pool.apply_async(foo, ('world', 'foo')) # tuple of args for foo

# do some other stuff in the main process

return_val = async_result.get()  # get the return value from your function.
-
this is the best answer as it's non-intrusive –  Jayen yesterday

One way I've seen is to pass a mutable object, such as a list or a dictionary, to the thread's constructor, along with a an index or other identifier of some sort. The thread can then store its results in its dedicated slot in that object. For example:

def foo(bar, result, index):
print 'hello {0}'.format(bar)
result[index] = "foo"

results = [None] * 10

# do some other stuff

print " ".join(results)  # what sound does a metasyntactic locomotive make?

If you really want join() to return the return value of the called function, you can do this with aThread subclass like the following:

from threading import Thread

def foo(bar):
print 'hello {0}'.format(bar)
return "foo"

def __init__(self, group=None, target=None, name=None,
args=(), kwargs={}, Verbose=None):
Thread.__init__(self, group, target, name, args, kwargs, Verbose)
self._return = None
def run(self):
def join(self):
return self._return

twrv.start()
print twrv.join()   # prints foo

That gets a little hairy because of some name mangling, and it accesses "private" data structures that are specific to Thread implementation... but it works.

-
thanks, i can see that that would be fine as a workaround, but it changes the function definition so that it doesn't really return anything. i wanted to know in my original case, where does that 'foo' actually go...? – wim Aug 2 '11 at 3:53
@wim: Return values go somewhere only if you put them somewhere. Unfortunately, in the case of Thread, all that happens inside the class -- the default run() method does not store off the return value, so you lose it. You could write your own Thread subclass to handle this, though. I've taken a whack at it in my message. –  kindall Aug 3 '11 at 1:20
cool, thanks for the example! i wonder why Thread was not implemented with handling a return value in the first place, it seems like an obvious enough thing to support. –  wim Aug 3 '11 at 1:28

Jake's answer is good, but if you don't want to use a threadpool (you don't know how many threads you'll need, but create them as needed) then a good way to transmit information between threads is the built-inQueue.Queue class, as it offers thread safety.

I created the following decorator to make it act in a similar fashion to the threadpool:

def threaded(f, daemon=False):
import Queue

def wrapped_f(q, *args, **kwargs):
'''this function calls the decorated function and puts the
result in a queue'''
ret = f(*args, **kwargs)
q.put(ret)

def wrap(*args, **kwargs):
'''this is the function returned from the decorator. It fires off
the result queue attached'''

q = Queue.Queue()

t.daemon = daemon
t.start()
t.result_queue = q
return t

return wrap

Then you just use it as:

@threaded
import time
x = x + 5
time.sleep(5)
return x

# does not block, returns Thread object
print y

# this blocks, waiting for the result
result = y.result_queue.get()
print result

The decorated function creates a new thread each time it's called and returns a Thread object that contains the queue that will receive the result.

-
I can't seem to get this to work; I get an error stating AttributeError: 'module' object has no attribute 'Lock' this appears to be emanating from the line y = long_task(10)... thoughts? – sadmicrowave Sep 13 at 2:26
The code doesn't explicitly use Lock, so the problem could be somewhere else in your code. You may want to post a new SO question about it –  bj0 Sep 14 at 4:18

join always return None, i think you should subclass Thread to handle return codes and so.

-

My solution to the problem is to wrap the function and thread in a class. Does not require using pools,queues, or c type variable passing. It is also non blocking. You check status instead. See example of how to use it at end of code.

import threading

'''
The basic idea is given a function create an object.
The object can then run the function in a thread.
It provides a wrapper to start it,check its status,and get data out the function.
'''
def __init__(self,func):
self.data = None
self.func = self.save_data(func)

def save_data(self,func):
'''modify function to save its returned data'''
def new_func(*args, **kwargs):
self.data=func(*args, **kwargs)

return new_func

def start(self,params):
self.data = None
return 'running' #could raise exception here

#unless thread exists and is alive start or restart it
return 'started'

def status(self):
return 'not_started'
else:
return 'running'
else:
return 'finished'

def get_results(self):
return 'not_started' #could return exception
else:
return 'running'
else:
return self.data

return x +y

print add_worker.get_results()
-
• 本文已收录于以下专栏：

## How can I get a String from HID device in Python with evdev?

http://stackoverflow.com/questions/19732978/how-can-i-get-a-string-from-hid-device-in-python-with-ev...

## How to Get the Most from Today’s Advanced EDA Tools

• 2010-12-28 19:45
• 219KB
• 下载

## How to Measure Anything Finding the Value of Intangibles in Business

• 2010-02-08 11:50
• 2.28MB
• 下载

## How-to Guide%3a Implement Value Helps in GenIL Components

• 2014-02-24 17:14
• 241KB
• 下载

## 转载：how to automate Microsoft Excel and return the values from a multi-cell range to an array

how to automate Microsoft Excel and return the values from a multi-cell range to an array.

## How to inject value into bean properties in Spring

In Spring, there are three ways to inject value into bean properties. Normal way Shortcut “p” schema...

## How to set value of Q0000-MASSN in FM HR_INFOTYPE_OPERATION

In fact HR_INFOTYPE_OPERATION is calling HR_MAINTAIN_MASTERDATA(BDC of PA30 actually), and it has a ...

## How to get the Values of Selected Row from a Gridview using ASP.NET

In this Article you can learn how to get the values of selected row from a Gridview and display the ...