赋值前引用的“tb”

2024-06-26 12:56:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我在我的项目中使用from multiprocessing.dummy import Pool。问题是,在多次成功尝试(获取price)后,它返回UnboundLocalError: local variable 'tb' referenced before assignment。你知道吗

问题是tb变量在被引用时应该100%赋值。如果存在异常,tb被赋值,否则,返回变量d,并且tb不被引用。你知道吗

我不知道哪里出了问题。我将向您展示我的函数-您可以看到变量tb,它是一个traceback,在引用它时,必须在所有情况下赋值:

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周期性的任务。你知道吗


Tags: toinpyscanlinecodemsgresult
1条回答
网友
1楼 · 发布于 2024-06-26 12:56:24

您没有捕获所有可能的异常,因此如果您得到的异常不是Exception的子类,那么except块和else块都不会执行,但是finally块仍然会执行。你知道吗

我将把return语句放在else中,并将finally块的内容移到主体中。然后你可能会看到任何BaseException引起的麻烦。你知道吗

相关问题 更多 >