2017-08-26 93 views
0

我想創建一個裝飾器,它可以讓函數在其自己的線程中運行。 而且我也想使用一個隊列作爲裝飾器的arg,這樣我就可以得到函數的返回值。 像這樣:帶多線程的Python裝飾器

import queue 
result = queue.Queue 
@thread(result) 
def function(args): 
    print ("Hello World!") 
    return args 
function("Hello Everyone!") 
print (result.get()) 

先入爲主,代碼將得到以下輸出:

Hello World!

Hello Everyone!

所以我寫這樣的代碼:

def thread(resultQueue = None): 
    def wrapper(function): 
     def process(*args, **kwargs): 
      ret = function(*args, **kwargs) 
      if resultQueue : resultQueue.put(ret) 
      return resultQueue 
     thread = threading.Thread(target = process) 
     thread.setDaemon(True) 
     thread.start() 
     return process 
    return wrapper 
a = queue.Queue() 

@basic.thread(a) 
def test(arg): 
    print (arg) 
    time.sleep(3) 
    return arg[::-1] 
test("Hello World!") 
print ("Hello!") 
print (a.get()) 

但我得到這個錯誤:

Exception in thread Thread-1: 
Traceback (most recent call last): 
    File "C:\Python34\lib\threading.py", line 911, in _bootstrap_inner 
    self.run() 
    File "C:\Python34\lib\threading.py", line 859, in run 
    self._target(*self._args, **self._kwargs) 
    File "test.py", line 214, in process 
    ret = function(*args, **kwargs) 
TypeError: test() missing 1 required positional argument: 'arg' 

爲什麼我有這個例外,我該如何解決這個問題?

謝謝!

+1

https://stackoverflow.com/questions/14234547/threads-with-decorators如果你需要解釋讓我知道。 – snahor

回答

1

您正在wrapper函數中創建新的Thread。相反,你需要在它內部定義一個新的方法來創建Thread。

def thread(resultQueue=None): 
    def wrapper(function): 
     def pw(*args, **kwargs): 
      def process(*args, **kwargs): 
       # print(args, kwargs) 
       ret = function(*args, **kwargs) 
       if resultQueue: 
        resultQueue.put(ret) 
       # return resultQueue 
      thread = threading.Thread(target=process, args=args, kwargs=kwargs) 
      thread.setDaemon(True) 
      thread.start() 
      return process 
     return pw 
    return wrapper 

而且您還需要將參數傳遞給線程構造函數。這是你得到錯誤的原因。