Как вернуть значение функции с декоратором и потоком - PullRequest
2 голосов
/ 19 мая 2009

имеют этот код

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))

но функция никогда не возвращает значение, выход из способа получить возврат?

Ответы [ 2 ]

4 голосов
/ 19 мая 2009

Причина возврата None заключается в том, что возвращать нечего (кроме того факта, что decorator не имеет оператора возврата). join() всегда возвращает None, согласно документации .

Пример взаимодействия с потоком см. В этом электронном письме .

Если я могу спросить: поскольку join() блокирует вызывающий поток, что здесь можно получить?


Редактировать: Я немного поиграл, и следующее решение, которое не требует очереди (не говоря уже о том, что это лучшее решение. Просто другое):

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))
2 голосов
/ 19 мая 2009

Это потому, что вы никогда не возвращаете значение в вашей функции декоратора.

Вы должны включить переменную общего доступа в свой поток и переместить возвращаемое значение вашей потоковой функции обратно в функцию "decorator".

...