私のプロジェクトで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
定期タスクです。
ありがとう、私はすべての例外は例外のサブクラスでなければならないと考えました。私はあなたの解決策を試してみますが、 'except except e'を' except: 'に変更すればどうでしょうか?それは正しく動作しますか? –
@MilanoSlesarikおそらく、いくつかの例外は非常に重要であり、アプリケーションの再スローや停止は危険であると考えられます。 – zch