Короче говоря, у меня есть серьезное приложение Python, которое, помимо прочего, выполняет исходящие вызовы для «losetup», «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
Это то, что обычно делается? Есть ли способ лучше? Возможно, деструктор в одноэлементном классе?






Обработчик широкого приложения в порядке. Они отлично подходят для лесозаготовок. Просто убедитесь, что широкое приложение долговечно и вряд ли выйдет из строя.
Мне вообще нравятся обработчики исключений верхнего уровня (независимо от языка). Это отличное место для очистки ресурсов, которые могут не иметь непосредственного отношения к ресурсам, потребляемым внутри метода, вызывающего исключение.
Это также фантастическое место для бревно этих исключений, если у вас есть такая структура. Обработчики верхнего уровня перехватят эти странные исключения, которые вы не планировали, и позволят вам исправить их в будущем, иначе вы можете вообще никогда не узнать о них.
Просто будьте осторожны, чтобы ваш обработчик верхнего уровня не создавал исключений!
Я также предлагаю вам поместить их в консольные приложения, которые выполняют пакетную обработку. Я прошу их разослать электронное письмо, чтобы мы могли получать уведомления о любых проблемах, но, по крайней мере, они могли зарегистрировать это.
Деструктор (как в методе __del__) - плохая идея, поскольку его вызов не гарантируется. Модуль atexit - более безопасный подход, хотя он все равно не сработает, если произойдет сбой интерпретатора Python (а не приложения Python), или если используется os._exit (), или процесс агрессивно завершен, или машина перезагружается. (Конечно, последний элемент не является проблемой в вашем случае.) Если ваш процесс подвержен сбоям (например, он использует непостоянные сторонние модули расширения), вы можете выполнить очистку в простом родительском процессе для больше изоляции.
Если вас это не особо беспокоит, воспользуйтесь модулем atexit.
Я не был полностью уверен, что деструктор будет вызван. Благодарю за разъяснение! Похоже, что atexit - это то, что мне нужно.
Это кажется разумным подходом, более простым и надежным, чем деструктор для одноэлементного класса. Вы также можете посмотреть модуль «атексит». (Произносится «на выходе», а не «текс ит» или что-то в этом роде. Я это долго не понимал.)
если вы используете классы, вы, конечно, должны освободить ресурсы, которые они выделяют в своих деструкторах. Используйте try: для всего приложения, только если вы хотите освободить ресурсы, которые еще не были освобождены деструкторами ваших классов.
И вместо использования универсального кода, кроме:, вы должны использовать следующий блок:
try:
main()
finally:
cleanup()
Это обеспечит очистку более питоническим способом.
Подумайте о написании диспетчера контекста и использовании оператора with.
Обработчики исключений верхнего уровня полезны в приложениях с графическим интерфейсом пользователя. Неперехваченные исключения, созданные в обработчиках событий, будут отображаться в консоли, но в целом не приведут к сбою программы (например, в PyGTK и PyQt), это может остаться незамеченным. Если вы показываете диалоговое окно с ошибкой в обработчике, у вас нет этой проблемы.