Из коробки atexit
не совсем подходит для того, что вы хотите сделать: он в основном используется для очистки ресурсов в самый последний момент, когда все закрывается и завершается.По аналогии, это «finally» попытки / исключения, тогда как вы хотите «еще» попытки / исключения.
Самый простой способ, о котором я могу подумать, - это продолжать создавать глобальный флаг, который вы устанавливаете только тогда, когда ваш скрипт «завершается успешно» ... и затем все функции, которые вы прикрепляете к atexit
, проверяют этот флаг,ничего не делать, если он не установлен.
Например:
_success = False
def atsuccess(func, *args, **kwds):
def wrapper():
if _success:
func(*args,**kwds)
atexit(wrapper)
def set_success():
global _success
_success = True
# then call atsuccess() to attach your callbacks,
# and call set_success() before your script returns
Одно ограничение - если у вас есть какой-либо код, который вызывает sys.exit(0)
перед установкой флага успеха.Такой код (вероятно) следует реорганизовать, чтобы сначала вернуться к основной функции, чтобы вы вызывали set_success
и sys.exit
только в одном месте.В противном случае вам нужно добавить что-то вроде следующей оболочки вокруг главной точки входа в вашем скрипте:
try:
main()
except SystemExit, err:
if err.code == 0:
set_success()
raise