2017-02-11 20 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定期タスクです。

答えて

1

あなたはすべての可能な例外をキャッチされていないので、あなたはExceptionのサブクラスではない例外を取得する場合、その後exceptブロックもelseブロックでもないが実行されますが、finallyブロックがまだ実行されます。

私はelsereturn文を入れて本体にfinallyブロックの内容を移動します。すると、BaseExceptionが問題を引き起こすものを見ることができるでしょう。

+0

ありがとう、私はすべての例外は例外のサブクラスでなければならないと考えました。私はあなたの解決策を試してみますが、 'except except e'を' except: 'に変更すればどうでしょうか?それは正しく動作しますか? –

+0

@MilanoSlesarikおそらく、いくつかの例外は非常に重要であり、アプリケーションの再スローや停止は危険であると考えられます。 – zch

関連する問題