Наконец, против atexit

В конечном итоге мне приходится писать и поддерживать короткие сценарии оболочки Python со следующей структурой высокого уровня:

try:
    code
    ...
    ...
except:
    raise
finally:
    file_handle.close()
    db_conn.close()

Обратите внимание, что все, что я делаю в except блок повторно вызывает исключение для скрипта вызывающего абонента без оформления окна; это не проблема в моем конкретном контексте. Идея в том, что код очистки всегда должен выполняться с помощью finally блок, исключение или нет.

Мне лучше использовать atexit обработчик для этого? Я мог бы обойтись без дополнительного уровня отступа, введенного try,

3 ответа

Решение

Просто используйте contextlib.closing

with closing(resource1) as f1, closing(resource2) as f2:
    f1.something()
    f2.something()

И они будут автоматически закрыты. Файловые объекты могут использоваться непосредственно как контексты, поэтому вам не нужно closing вызов.

Если close это не единственный метод, используемый вашими ресурсами, вы можете создавать собственные функции с помощью contextlib.contextmanager декоратор.

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

import atexit

def cleanup():
    print 'performimg cleanup'

# multiple functions can be registered here...    
atexit.register(cleanup)

Модуль sys также предоставляет хук sys.exitfunc, но там может быть зарегистрирована только одна функция.

Finally сопровождается try except блок, функциональность finally может также использоваться для чего-то подобного, например, очистки, finally Блок sys.exc_info - это все-Нет.

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

Другая pro-con является atexit функции выполняются только после завершения программы, однако вы можете использовать finally (с try-исключением) в любом месте кода и выполнить очистку

В вашем сценарии, где вы хотите вызвать исключение из контента очистки, использование atexit было бы полезно, если вы в порядке для очистки в конце программы

atexit вызывается после завершения программы, так что это не то, что вы ищете.

Другие вопросы по тегам