2017-02-11 1 views
0

내 프로젝트에 from multiprocessing.dummy import Pool을 사용합니다. 문제는 많은 성공한 시도 (가격을 받고) 후에 UnboundLocalError: local variable 'tb' referenced before assignment을 반환한다는 것입니다.할당 전에 tb가 참조 됨

변수는 참조 될 때 tb 변수가 100 % 할당되어야합니다. 예외가있는 경우 tb이 지정되고, 그렇지 않으면 변수 d이 반환되고 tb은 참조되지 않습니다.

어디에서 문제가 될 수 있는지 알 수 없습니다. - 내가 당신에게 내 기능을 보여줍니다 당신이하는 traceback입니다 변수 tb을 볼 수있는 것은 그것의 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 정기 작업입니다. 당신이 Exception 다음도 except 블록도 실행됩니다 else 블록의 서브 클래스가 아니라 finally 블록이 여전히 실행됩니다 예외가 그래서 만약

답변

1

당신은 가능한 모든 예외를 잡기되지 않습니다.

return 문을 else에 넣고 본체 내용을 finally 블록으로 옮깁니다. 그러면 BaseException이 문제를 일으키는 것을 볼 수 있습니다.

+0

감사합니다. 모든 예외는 Exception의 하위 클래스 여야한다고 생각했습니다. 나는 당신의 해결책을 시도 할 것이지만 만약'except except e'를'except :'로 변경한다면? 올바르게 작동할까요? –

+0

@MilanoSlesarik 아마도 일부 예외는 매우 중요하므로 응용 프로그램을 다시 시작하거나 중지하지 않으면 위험한 것으로 간주 될 수 있습니다. – zch