Имеет ли смысл обработчик исключений в приложении? - PullRequest
10 голосов
/ 18 сентября 2008

Короче говоря, у меня есть существенное приложение на Python, которое, помимо прочего, превосходит "losttup", "mount" и т.д. в Linux. Потребление системных ресурсов, которые должны быть освобождены после завершения.

В случае сбоя моего приложения я хочу убедиться, что эти системные ресурсы освобождены должным образом.

Имеет ли смысл сделать что-то вроде следующего?

def main():
    # TODO: main application entry point
    pass

def cleanup():
    # TODO: release system resources here
    pass

if __name__ == "__main__":
    try:
        main()
    except:
        cleanup()
        raise

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

Ответы [ 6 ]

11 голосов
/ 18 сентября 2008

Мне нравятся обработчики исключений верхнего уровня в целом (независимо от языка). Они являются отличным местом для очистки ресурсов, которые могут не иметь непосредственного отношения к ресурсам, потребляемым внутри метода, который вызывает исключение.

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

Только будьте осторожны, чтобы ваш обработчик верхнего уровня не генерировал исключения!

7 голосов
/ 18 сентября 2008

Деструктор (как в методе __del__) является плохой идеей, так как он не гарантированно вызывается. Модуль atexit является более безопасным подходом, хотя он все равно не сработает, если произойдет сбой интерпретатора Python (а не приложения Python), или если используется os._exit (), или процесс будет агрессивно завершен или машина перезагрузится. (Конечно, последний элемент не является проблемой в вашем случае.) Если ваш процесс подвержен сбоям (например, используются нестабильные сторонние модули расширения), вы можете выполнить очистку в простом родительском процессе для больше изоляции.

Если вы на самом деле не беспокоитесь, используйте модуль atexit.

2 голосов
/ 19 сентября 2008

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

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

try:
    main()
finally:
    cleanup()

Это обеспечит очистку более питоническим способом.

2 голосов
/ 18 сентября 2008

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

1 голос
/ 23 сентября 2008

Попробуйте написать менеджер контекста и использовать оператор with.

1 голос
/ 18 сентября 2008

Это кажется разумным подходом, более простым и надежным, чем деструктор в одном классе. Вы также можете посмотреть на модуль " atexit ". (Произносится «на выходе», а не «текст это» или что-то в этом роде. Я запутался в этом надолго.)

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