Попробуй еще Python - PullRequest
       28

Попробуй еще Python

493 голосов
/ 13 мая 2009

Как предполагается использовать необязательное предложение else оператора try?

Ответы [ 20 ]

761 голосов
/ 13 мая 2009

Операторы в блоке else выполняются, если выполнение падает в нижней части try - если не было исключений. Честно говоря, я никогда не нашел в этом необходимости.

Однако Обработка исключений Примечания:

Лучше использовать предложение else чем добавить дополнительный код для попытки пункт, потому что он избегает случайно поймать исключение, которое не было поднят код, защищенный попытка ... кроме утверждения.

Итак, если у вас есть метод, который может, например, бросить IOError, и вы хотите отлавливать исключения, которые он вызывает, но есть еще кое-что, что вы хотите сделать, если первая операция выполнена успешно, и вы не хочет отлавливать IOError из этой операции, вы можете написать что-то вроде этого:

    try:
        operation_that_can_throw_ioerror()
    except IOError:
        handle_the_exception_somehow()
    else:
         # we don't want to catch the IOError if it's raised
        another_operation_that_can_throw_ioerror()
    finally:
        something_we_always_need_to_do()

Если вы просто поставите another_operation_that_can_throw_ioerror() после operation_that_can_throw_ioerror, except перехватит ошибки второго вызова. И если вы поместите его после всего блока try, он всегда будет запущен, и только после finally. else позволяет вам убедиться,

  1. вторая операция запускается, только если нет исключений,
  2. запускается перед блоком finally, а
  3. любой IOError с, который он поднимает, здесь не пойман
87 голосов
/ 29 января 2013

Существует одна большая причина для использования else - стиль и удобочитаемость. Как правило, рекомендуется хранить код, который может вызывать исключения, рядом с кодом, который их обрабатывает. Например, сравните это:

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass

и

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword

Второй вариант хорош, когда except не может вернуться рано или повторно выдать исключение. Если возможно, я бы написал:

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')

# 20 other lines
getpass = AskPassword

Примечание: Ответ скопирован из недавно опубликованного дубликата здесь , отсюда и весь этот материал "AskPassword".

45 голосов
/ 13 мая 2009

Одно использование: протестировать некоторый код, который должен вызвать исключение.

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"

(Этот код следует абстрагировать в более общий тест на практике.)

36 голосов
/ 11 февраля 2015

Python try-else

Как предполагается использовать необязательное условие else оператора try?

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

Этот контекст позволяет избежать случайной обработки ошибок, которые вы не ожидали.

Но важно понимать точные условия, которые вызывают выполнение условия else, потому что return, continue и break могут прервать поток управления до else.

В итоге

Оператор else выполняется, если есть нет исключений и если он не прерывается оператором return, continue или break.

В других ответах пропущена последняя часть.

Из документов:

Необязательное предложение else выполняется, если и когда элемент управления вытекает из конец предложения try. *

(добавлен жирный шрифт.) И сноска гласит:

* В настоящее время управление «течет с конца», за исключением случая, когда исключение или выполнение оператора return, continue или break.

Требуется хотя бы одно предшествующее, кроме пункта ( см. Грамматику ). Так что на самом деле это не «try-else», это «try-кроме-else (окончательно)», с elsefinally), необязательным.

Python Tutorial развивает предполагаемое использование:

Оператор try ... Кроме имеет необязательное условие else, которое, когда настоящее, должны следовать всем, кроме пунктов. Это полезно для кода, который должен быть выполнен, если предложение try не вызывает исключение. За Пример:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

Использование условия else лучше, чем добавление дополнительного кода в предложение try, потому что оно позволяет избежать случайного отлова исключения это не было вызвано кодом, защищенным попыткой ... кроме заявление.

Пример дифференцирования else от кода, следующего за блоком try

Если вы обработаете ошибку, блок else не будет работать. Например:

def handle_error():
    try:
        raise RuntimeError('oops!')
    except RuntimeError as error:
        print('handled a RuntimeError, no big deal.')
    else:
        print('if this prints, we had no error!') # won't print!
    print('And now we have left the try block!')  # will print!

А теперь

>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!
18 голосов
/ 18 апреля 2015

Try-кроме-else отлично подходит для комбинирования паттерна EAFP с набором утки :

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()

Вы могли бы подумать, что этот наивный код подходит:

try:
  for v in x.cleanupSet:
    v.clenaup()
except AttributeError:
  pass

Это отличный способ случайно скрыть серьезные ошибки в вашем коде. Я опечатал там уборку, но ошибка AttributeError, которая дала бы мне знать, проглатывается. Хуже того, что если бы я написал это правильно, но метод очистки иногда передавал пользовательский тип, имеющий атрибут с неправильным именем, что приводило к молчаливому сбою на полпути и оставлению файла открытым Удачи в отладке этого.

15 голосов
/ 13 мая 2009

Я считаю, что это действительно полезно, когда нужно выполнить очистку, даже если есть исключение:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()
10 голосов
/ 13 мая 2009

Даже если вы не можете придумать, как его использовать прямо сейчас, вы можете поспорить, что его нужно использовать. Вот невообразимый образец:

С else:

a = [1,2,3]
try:
    something = a[2]
except:
    print "out of bounds"
else:
    print something

Без else:

try:
    something = a[2]
except:
    print "out of bounds"

if "something" in locals():
    print something

Здесь у вас есть переменная something, определенная, если не выдано никакой ошибки. Вы можете удалить это за пределами блока try, но тогда потребуется некоторое грязное обнаружение, если определена переменная.

8 голосов
/ 21 августа 2013

С Ошибки и исключения # Обработка исключений - docs.python.org

В операторе try ... except есть необязательное предложение else, которое, если присутствует, должен следовать всем, кроме пунктов. Это полезно для кода это должно быть выполнено, если предложение try не вызывает исключение. Например:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

Использование предложения else лучше, чем добавление дополнительного кода в предложение try, потому что оно позволяет избежать случайного отлова исключения это не было вызвано кодом, защищенным попыткой ... кроме заявление.

6 голосов
/ 27 мая 2009

Есть хороший пример try-else в PEP 380 . По сути, все сводится к разной обработке исключений в разных частях алгоритма.

Это примерно так:

try:
    do_init_stuff()
except:
    handle_init_suff_execption()
else:
    try:
        do_middle_stuff()
    except:
        handle_middle_stuff_exception()

Это позволяет записывать код обработки исключений ближе к месту возникновения исключения.

5 голосов
/ 13 мая 2009

Глядя на Ссылка на Python , кажется, что else выполняется после try, когда нет исключений. Необязательное условие else выполняется, если и когда управление выходит за пределы конца предложения try. 2 Исключения в предложении else не обрабатываются предыдущим, кроме пунктов.

Погружение в python есть пример, где, если я правильно понимаю, в блоке try они пытаются импортировать модуль, когда это не удается, вы получаете исключение и связываете значение по умолчанию, но когда это работает, у вас возможность перейти в блок else и связать то, что требуется (см. ссылку для примера и объяснения).

Если вы попытаетесь выполнить работу в блоке catch, это может вызвать другое исключение - я думаю, именно здесь пригодится блок else.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...