2017-02-11 40 views
0

我在我的項目中使用from multiprocessing.dummy import Pool。問題是,經過許多成功的嘗試(獲得價格)後,它返回UnboundLocalError: local variable 'tb' referenced before assignment'tb'在作業前提到

事情是tb變量應該100%分配時,它被引用。如果發生異常,則分配tb,否則返回變量d並且不引用tb

我不知道哪裏可能是問題。我會告訴你我的功能 - 你可以看到該變量tb,這是一個traceback,在所有情況下,被分配當其referrenced:

def scan_partner(d): 
    success = False 
    try: 
     from parser import parse_price 
     resp = get_price(d.get('url'), d.get('xpath')) 
     amount = resp.get('price') 

    except XPathEvalError as xee: 
     tb = traceback.format_exc() 
     ticket_code = 'xpath' 
     msg = u'XPath Error' 
    except (requests.Timeout, requests.ConnectTimeout, requests.ReadTimeout): 
     tb = traceback.format_exc() 
     ticket_code = 'timeout' 
     msg = u'Timeout' 
    except requests.HTTPError: 
     tb = traceback.format_exc() 
     ticket_code = 'http' 
     msg = u'HTTP Error' 
    except decimal.DecimalException: 
     tb = traceback.format_exc() 
     ticket_code = 'decimal' 
     msg = u'Decimal Error' 
    except requests.ConnectionError: 
     tb = traceback.format_exc() 
     ticket_code = 'connection' 
     msg = u'Connection Error' 
    except Exception as e: 
     tb = traceback.format_exc() 
     ticket_code = 'unknown' 
     msg = u'Unknown Error' 
    else: 
     success = True 
     result = {'result': {'success': True, 
          'amount': str(amount)}} 
     d.update(result) 

    finally: 
     if success: 
      return d 
     d.update({'ticket': {'tb': tb, 
          'msg': msg, 
          'ticket_code': ticket_code}, 
        'result': {'success': False}}) 
     return d 


def scan_partners_dummy_pool(dicts_list): 
    repeated_results = [] 

    results_to_repeat = [] 
    for i in range(settings.ENGINE_NUMBER_OF_SCAN_REPEATS): 
     pool = Pool(300) 
     results = pool.map(scan_partner, dicts_list) 
     pool.close() 
     pool.join() 
     results_to_go = [] 
     results_to_repeat = [] 
     for result in results: 
      if result['result']['success']: 
       results_to_go.append(result) 
      else: 
       if result['ticket']['ticket_code']=='timeout': 
        results_to_repeat.append(result) 
       else: 
        results_to_go.append(result) 
     repeated_results.extend(results_to_go) 
     dicts_list = results_to_repeat 
    repeated_results.extend(results_to_repeat) 

    return repeated_results 

回溯:

[2017-02-11 23:33:54,470: ERROR/MainProcess] Task engineapp.tasks.scan_every_20_minutes[91c08f5d-36ad-42bc-805f-8a35c01127e6] raised unexpected: UnboundLocalError("local variable 'tb' referenced before assignment",) 
Traceback (most recent call last): 
    File "c:\users\milano\pycharmprojects\dropboxworkspaces\priceist_workspace\priceist_venv\lib\site-packages\celery\app\trace.py", line 240, in trace_task 
    R = retval = fun(*args, **kwargs) 
    File "c:\users\milano\pycharmprojects\dropboxworkspaces\priceist_workspace\priceist_venv\lib\site-packages\celery\app\trace.py", line 438, in __protected_call__ 
    return self.run(*args, **kwargs) 
    File "C:\Users\Milano\Desktop\Projekty\FS Dropbox\Dropbox\priceist\engineapp\tasks.py", line 18, in scan_every_20_minutes 
    scan_all_active_users(20) 
    File "c:\users\milano\pycharmprojects\dropboxworkspaces\priceist_workspace\priceist_venv\lib\site-packages\celery\local.py", line 167, in <lambda> 
    __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw) 
    File "c:\users\milano\pycharmprojects\dropboxworkspaces\priceist_workspace\priceist_venv\lib\site-packages\celery\app\trace.py", line 439, in __protected_call__ 
    return orig(self, *args, **kwargs) 
    File "c:\users\milano\pycharmprojects\dropboxworkspaces\priceist_workspace\priceist_venv\lib\site-packages\celery\app\task.py", line 420, in __call__ 
    return self.run(*args, **kwargs) 
    File "C:\Users\Milano\Desktop\Projekty\FS Dropbox\Dropbox\priceist\engineapp\tasks.py", line 132, in scan_all_active_users 
    report = scan_user(user.id, simple_schedule) 
    File "C:\Users\Milano\Desktop\Projekty\FS Dropbox\Dropbox\priceist\engineapp\tasks.py", line 123, in scan_user 
    results = scan_partners_dummy_pool(partners_dicts) 
    File "C:\Users\Milano\Desktop\Projekty\FS Dropbox\Dropbox\priceist\engineapp\engine\scraper.py", line 126, in scan_partners_dummy_pool 
    if result['ticket']['ticket_code']=='timeout': 
    File "c:\python27\Lib\multiprocessing\pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "c:\python27\Lib\multiprocessing\pool.py", line 567, in get 
    raise self._value 
UnboundLocalError: local variable 'tb' referenced before assignment 

PS: 該過程是一個Celery定期任務。

回答

1

您還沒有捕獲所有可能的異常,所以如果你的例外是不是Exception則既不except塊也不else塊將執行子類,但finally塊將被下執行。

我會將return陳述放入else中,並將finally區塊的內容移到主體。那麼你可能會看到什麼BaseException造成麻煩。

+0

謝謝,我認爲每個異常都必須是異常的子類。我會嘗試你的解決方案,但如果我改變'除了例外作爲e'到'除了:'?它會正常工作嗎? –

+0

@MilanoSlesarik然而,也許請注意,一些例外如此重要以至於捕獲它們而不重新投擲或停止應用程序將被認爲是危險的。 – zch