2014-02-21 3 views
4

Я написал сканера для извлечения информации из Q & Веб-сайт. Поскольку не все поля представлены на странице все время, я использовал несколько пробных исключений для обработки ситуации.Catch exception получает UnboundLocalError

def answerContentExtractor(loginSession, questionLinkQueue , answerContentList) : 
    while True: 
     URL = questionLinkQueue.get() 
     try: 
      response = loginSession.get(URL,timeout = MAX_WAIT_TIME) 
      raw_data = response.text 

      #These fields must exist, or something went wrong... 
      questionId = re.findall(REGEX,raw_data)[0] 
      answerId = re.findall(REGEX,raw_data)[0] 
      title  = re.findall(REGEX,raw_data)[0] 

     except requests.exceptions.Timeout ,IndexError: 
      print >> sys.stderr, URL + " extraction error..." 
      questionLinkQueue.task_done() 
      continue 

     try: 
      questionInfo = re.findall(REGEX,raw_data)[0] 
     except IndexError: 
      questionInfo = "" 

     try: 
      answerContent = re.findall(REGEX,raw_data)[0] 
     except IndexError: 
      answerContent = "" 

     result = { 
        'questionId' : questionId, 
        'answerId'  : answerId, 
        'title'  : title, 
        'questionInfo' : questionInfo, 
        'answerContent': answerContent 
        } 

     answerContentList.append(result) 
     questionLinkQueue.task_done() 

И этот код, иногда, может или не может, дает следующее исключение во время выполнения:

UnboundLocalError: local variable 'IndexError' referenced before assignment 

Номер строки указывает ошибка происходит на втором except IndexError:

Спасибо всем за ваши предложения, хотел бы дать оценки, которые вы заслуживаете, слишком плохо, я могу отметить только один как правильный ответ ...

+0

опечаток, я руку напечатал его полосатые некоторые ип - выделенные строки .. Отредактировано уже .. –

+0

Связано: [несколько исключений в одной строке (кроме блока) ] (http://stackoverflow.com/questions/6470428/catch-multiple-exceptions-in-one-line-except-block?rq=1) – thefourtheye

ответ

6

Я думаю, что проблема эта линия:

except requests.exceptions.Timeout ,IndexError 

Это эквивалентно:

except requests.exceptions.Timeout as IndexError: 

Итак, вы присваиваете IndexError к исключение поймали requests.exceptions.Timeout. Ошибка может быть воспроизведена с помощью этого кода:

try: 
    true 
except NameError, IndexError: 
    print IndexError 
    #name 'true' is not defined 

поймать несколько исключений использовать кортеж:

except (requests.exceptions.Timeout, IndexError): 

И UnboundLocalError приходит потому, что IndexError рассматривается как локальная переменная по вашей функции, поэтому пытается получить доступ его значение до фактического определения поднимет ошибку UnboundLocalError.

>>> 'IndexError' in answerContentExtractor.func_code.co_varnames 
True 

Таким образом, если эта строка не выполняется во время выполнения (requests.exceptions.Timeout ,IndexError), то IndexError переменная, используемая под ним поднимет UnboundLocalError. Образец кода для воспроизведения ошибки:

def func(): 
    try: 
     print 
    except NameError, IndexError: 
     pass 
    try: 
     [][1] 
    except IndexError: 
     pass 
func() 
#UnboundLocalError: local variable 'IndexError' referenced before assignment 
+1

Это решило проблему. Спасибо, что объяснили все материалы за сцена. Я получил гораздо лучшее представление о коде, кроме исправления ошибки. Еще раз спасибо .. –

+0

@PaulLeung Рад, что помогло. :) –

2

Когда вы говорите

except requests.exceptions.Timeout ,IndexError: 

Питон за исключением requests.exceptions.Timeout ошибки и объект ошибка будет IndexError. Это должно было быть что-то вроде этого

except (requests.exceptions.Timeout ,IndexError) as e: 
1
except requests.exceptions.Timeout ,IndexError: 

означает то же самое, как except requests.exceptions.Timeout as IndexError

Вы должны использовать

except (requests.exceptions.Timeout, IndexError): 

вместо