Когда нужно добавить предложение `else` в try..except в Python?

Когда я пишу код в Python с обработкой исключений, я могу написать код вроде:

try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()
else:
    code_that_needs_to_run_when_there_are_no_exceptions()

Как это отличается от:

try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()

code_that_needs_to_run_when_there_are_no_exceptions()

В обоих случаях code_that_needs_to_run_when_there_are_no_exceptions() будет выполняться, если исключений нет. Какая разница?

Ответ 1

Собственно, во втором фрагменте последняя строка выполняется всегда.

Вероятно, вы имели в виду

try:
    some_code_that_can_cause_an_exception()
    code_that_needs_to_run_when_there_are_no_exceptions()
except:
    some_code_to_handle_exceptions()

Я считаю, что вы можете использовать версию else, если она делает код более читаемым. Вы используете вариант else, если вы не хотите ловить исключения из code_that_needs_to_run_when_there_are_no_exceptions.

Ответ 2

Во втором примере code_that_needs_to_run_when_there_are_no_exceptions() будет выполняться, если вы сделаете, имеете исключение, а затем обрабатываете его, продолжая после исключения.

так...

В обоих случаях код_that_needs_to_run_when_there_are_no_exceptions() будет выполняться, если нет исключений, но в последнем будет выполняться, когда есть и не являются исключениями.

Попробуйте это на своем CLI

#!/usr/bin/python

def throws_ex( raise_it=True ):
        if raise_it:
                raise Exception("Handle me")

def do_more():
        print "doing more\n"

if __name__ == "__main__":
        print "Example 1\n"
        try:
                throws_ex()
        except Exception, e:
                # Handle it
                print "Handling Exception\n"
        else:
                print "No Exceptions\n"
                do_more()

        print "example 2\n"
        try:
                throws_ex()
        except Exception, e:
                print "Handling Exception\n"
        do_more()

        print "example 3\n"
        try:
                throws_ex(False)
        except Exception, e:
                print "Handling Exception\n"
        else:
                do_more()

        print "example 4\n"
        try:
                throws_ex(False)
        except Exception, e:
                print "Handling Exception\n"
        do_more()

Он выведет

Пример 1

Обработка исключений

пример 2

Обработка исключений

делать больше

Пример 3

делать больше

Пример 4

делать больше

Вы получаете идею играть вокруг с исключениями, пузырями и прочими вещами! Извлеките командную строку и VIM!

Ответ 3

Пример 1:

try:
    a()
    b()
except:
    c()

Здесь b() будет выполняться только в том случае, если a() не выбрасывает, но блок except также поймает любые исключения, которые могут быть выбраны b(), что вам может и не понадобиться. Общее правило заключается в том, что вы можете исключать только исключения, которые, как вы знаете, могут иметь место (и иметь способ обработки). Поэтому, если вы не знаете, будет ли b() бросать, или если вы не можете сделать ничего полезного, поймав исключение, созданное b(), тогда не ставьте b() в блок try:.

Пример 2:

try:
    a()
except:
    c()
else:
    b()

Здесь b() будет выполняться только в том случае, если a() не выбрасывает, но любые исключения, которые b() throws не будут пойманы здесь и будут продолжать распространять стек. Это очень часто то, что вы хотите.

Пример 3:

try:
    a()
except:
    c()

b()

Здесь b() всегда запускается, даже если a() ничего не выбрасывает. Конечно, это тоже довольно полезно.

Ответ 4

У вас был исходный код почти справа. Здесь полное лечение:

try:
    some_code_that_can_cause_an_exception()
except:
    some_code_to_handle_exceptions()
else:
    code_that_needs_to_run_when_there_are_no_exceptions()

code_that_runs_whether_there_was_an_exception_or_not()

Ответ 5

В то время как ответ Ned Batchelder подходит для OP, я хотел бы немного опираться на него. Кроме того, я не могу ответить как комментарий к комментарию Mk12 (так как у меня "только" есть 49 репутации, а не 50, идите на фигуру). Итак, мой лексический вклад:

try:
    code_that_can_cause_an_exception()
except ParticularException:
    code_to_handle_the_particular_exception()
except:
    code_to_handle_all_other_exceptions()
else:
    code_to_run_when_there_are_no_exceptions_and_which_should_not_be_run_after_except_clauses()
finally:
    code_to_run_whether_there_was_an_exception_or_not_even_if_the_program_will_exit_from_the_try_block()

code_to_run_whether_there_was_an_exception_or_not_if_execution_reaches_here()

Ответ 6

В соответствии с docs...

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

Итак, посмотрите на этот базовый пример как на свой ответ

try:
  print("Try with Exception")
  print(sys.path)
except NameError:
  print "Exception"
else:
  print "Else"

print("Out of try/except block")

try:
  print("Try without Exception")
except NameError:
  print "Exception"
else:
  print "Else is now executed"

print("Out of try/except finally")

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

Ответ 7

Я использую try:.. за исключением:.. else: много!

Это шаблон: try..except должен охватывать только одну строку кода, где я ожидаю исключения. Затем, за исключением обработки с возвратом/по умолчанию, а также: делает то, что я действительно хотел сделать (никаких исключений = > продолжать делать то, что я хотел).

Простой пример:

   # Exhibit 1
   data_paths = []
   try:
       from . import version_subst
   except ImportError:
       first_datadir = "./data"
   else:
       first_datadir = os.path.join(version_subst.DATADIR, PACKAGE_NAME)


# Exhibit 2
for attr in attrs:
    try:
        obj = getattr(plugin, attr)
    except AttributeError, e:
        if warn:
            pretty.print_info(__name__, "Plugin %s: %s" % (plugin_name, e))
        yield None
    else:
        yield obj

Ответ 8

Я не использовал Python так долго, но я стараюсь обрабатывать определенные исключения в блоке try и использовать else для обработки "других" исключений, которые я, возможно, не ожидал, подобно default в блоках C/С++ switch. Является ли это подходящим использованием для else?