Как вернуть значение и вызвать исключение

У меня есть две цели с этим try/except заявление.

  1. Нужно return значение 1, если проблем не возникло, или 0, если возникли проблемы.
  2. Нужно вызвать исключение и завершить скрипт.

у меня есть return ценность рабочая. У меня также есть SystemExit() за работой. Но вместе они не работают.

Мой Python Script (это актуально):

except IOError:
    value_to_return = 0
    return value_to_return
    raise SystemExit("FOOBAR")

При этом он игнорирует raise SystemExit("FOOBAR") линия полностью. Как мне получить возвращаемое значение и до сих пор raise SystemExit("FOOBAR")? Для некоторых это может быть элементарно, но на самом деле у меня с этим немало трудностей.

4 ответа

Решение

Возвращение и повышение взаимоисключающие.

привлечение SystemExit закончит сценарий. Несколько процедур очистки запускаются, и если вызывающий действительно, действительно хочет, они могут поймать SystemExit и отмените его, но в основном вы можете думать об этом как об остановке исполнения прямо здесь. Вызывающая сторона никогда не получит возможность увидеть возвращаемое значение или сделать что-либо значимое с ним.

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

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

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

Другой питонический ответ на вашу проблему может заключаться в использовании аргументов ошибки в повышении, а затем в вашем вызове управлять ошибкой, чтобы получить значение, преобразовать его из строки и получить свой "return-ish".

def your_f():
    try:
      some_io_thingy_ok()
      return 1
    except IOError:
        raise SystemExit("FOOBAR", 0)

try:
    my_returning_value = your_f()
except SystemExit as err:
    my_returning_value = err.args[1]


print(my_returning_value)

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

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

В предложении except может быть указана переменная после имени исключения. Переменная привязана к экземпляру исключения с аргументами, хранящимися в instance.args. Для удобства в экземпляре исключения определена функцияstr(), поэтому аргументы могут быть напечатаны напрямую без ссылки на.args. Можно также сначала создать экземпляр исключения перед его возбуждением и добавить к нему любые атрибуты по желанию.

Чтобы выйти из скрипта и вернуть статус выхода, используйте sys.exit():

import sys
sys.exit(value_to_return)

Вы не можете "поднимать" и "возвращать" одновременно, поэтому вы должны добавить специальную переменную к возвращаемому значению (например, в кортеже) в случае ошибки.

Например: у меня есть функция (названная "func"), которая подсчитывает что-то, и мне нужен (частичный) результат, даже если во время подсчета произошло исключение. В моем примере я буду использовать исключение KeyboardInterrupt (пользователь нажал CTRL-C).

Без обработки исключений в функции (это неправильно, в случае каких-либо исключений функция ничего не возвращает):

def func():
    s=0
    for i in range(10):
        s=s+1
        time.sleep(0.1)
    return s


x=0
try:
    for i in range(10):
       s=func()
       x=x+s
except KeyboardInterrupt:
    print(x)
else:
    print(x)

А теперь я ввел логическое возвращаемое значение (в кортеже рядом с исходным возвращаемым значением), чтобы указать, произошло ли исключение. Поскольку в функции я обрабатываю только исключение KeyboardInterrupt, я могу быть уверен, что это произошло, поэтому я могу вызвать то же самое, где я вызвал функцию:

def func():
    try:
        s=0
        for i in range(10):
            s=s+1
            time.sleep(0.1)
    except KeyboardInterrupt: # <- the trick is here
        return s, True        # <- the trick is here
    return s, False           # <- the trick is here


x=0
try:
    for i in range(10):
        s,e=func()
        x=x+s
        if e:                         # <- and here
            raise KeyboardInterrupt   # <- and here
except KeyboardInterrupt:
    print(x)
else:
    print(x)

Примечание: мой пример - python3. Модуль времени используется (в обоих кодах выше), но я не импортировал его только для того, чтобы сделать его короче. Если вы действительно хотите попробовать, поставьте в начале:

import time

Я искал ответ, не используя try, используйте ключевое слово 'finally' вот так... если кто-нибудь знает, заполните меня, вот ответ на вашу проблему

try:
    9/0#sample error "don't know how to make IOError"
except ZeroDivisionError:
    value_to_return = 0
    raise SystemExit("FOOBAR")
finally:return value_to_return

Я думаю, что вы можете искать что-то вроде этого:

def some_function():
    # this function should probably do some stuff, then return 1 if
    # it was successful or 0 otherwise.
    pass

def calling_function():
    a = some_function()
    if a == 1:
        raise SystemExit('Get the heck outta here!')
    else:
        # Everything worked!
        pass
Другие вопросы по тегам