> **Источник:** https://python-all.ru/2.7/library/atexit.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 28.9. [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) – Обработчики выхода

Новое в версии 2.0.

**Исходный код:** [Lib/atexit.py](https://python-all.ru/src/2.7/Lib/atexit.py)

---

Модуль [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) определяет одну функцию для регистрации функций очистки. Зарегистрированные таким образом функции автоматически выполняются при нормальном завершении интерпретатора. [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) запускает эти функции в *обратном* порядке их регистрации; если зарегистрировать `A`, `B` и `C`, при завершении интерпретатора они будут выполнены в порядке `C`, `B`, `A`.

**Примечание:** Функции, зарегистрированные через этот модуль, не вызываются, когда программа завершается по сигналу, не обрабатываемому Python, когда обнаружена фатальная внутренняя ошибка Python или при вызове [`os._exit()`](https://python-all.ru/2.7/library/os.html#os._exit).

Это альтернативный интерфейс для функциональности, предоставляемой переменной [`sys.exitfunc()`](https://python-all.ru/2.7/library/sys.html#sys.exitfunc).

Примечание: этот модуль вряд ли будет работать корректно при использовании с другим кодом, который устанавливает `sys.exitfunc`. В частности, другие основные модули Python могут свободно использовать [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) без ведома программиста. Авторам, использующим `sys.exitfunc`, следует переделать свой код на использование [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit). Проще всего преобразовать код, устанавливающий `sys.exitfunc`, – импортировать [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) и зарегистрировать функцию, которая была привязана к `sys.exitfunc`.

#### `atexit.register(func[, *args[, **kwargs]])`

Регистрирует *func* как функцию, которая будет выполнена при завершении. Все необязательные аргументы, которые должны быть переданы *func*, должны быть переданы как аргументы в [`register()`](https://python-all.ru/2.7/library/atexit.html#atexit.register). Можно зарегистрировать одну и ту же функцию и аргументы несколько раз.

При нормальном завершении программы (например, если вызывается [`sys.exit()`](https://python-all.ru/2.7/library/sys.html#sys.exit) или завершается выполнение главного модуля) все зарегистрированные функции вызываются в порядке последним вошёл – первым вышел. Предполагается, что модули нижнего уровня обычно импортируются раньше модулей верхнего уровня и, следовательно, должны быть очищены позже.

Если во время выполнения обработчиков выхода возникает исключение, выводится traceback (если только не возбуждено [`SystemExit`](https://python-all.ru/2.7/library/exceptions.html#exceptions.SystemExit)) и сохраняется информация об исключении. После того как все обработчики выхода получили возможность выполниться, последнее возбуждённое исключение возбуждается повторно.

Изменено в версии 2.6: Теперь эта функция возвращает *func*, что позволяет использовать её в качестве декоратора.

> **См. также**
>
> **Модуль [`readline`](https://python-all.ru/2.7/library/readline.html#module-readline)**
>
> Полезный пример [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) для чтения и записи файлов истории [`readline`](https://python-all.ru/2.7/library/readline.html#module-readline).

## 28.9.1. [`atexit`](https://python-all.ru/2.7/library/atexit.html#module-atexit) Пример

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

```python
try:
    _count = int(open("counter").read())
except IOError:
    _count = 0

def incrcounter(n):
    global _count
    _count = _count + n

def savecounter():
    open("counter", "w").write("%d" % _count)

import atexit
atexit.register(savecounter)
```

Позиционные и именованные аргументы также могут быть переданы в [`register()`](https://python-all.ru/2.7/library/atexit.html#atexit.register), чтобы быть переданными зарегистрированной функции при её вызове:

```python
def goodbye(name, adjective):
    print 'Goodbye, %s, it was %s to meet you.' % (name, adjective)

import atexit
atexit.register(goodbye, 'Donny', 'nice')

# или:
atexit.register(goodbye, adjective='nice', name='Donny')
```

Использование в качестве [декоратора](https://python-all.ru/2.7/glossary.html#term-decorator):

```python
import atexit

@atexit.register
def goodbye():
    print "You are now leaving the Python sector."
```

Это работает только с функциями, которые можно вызывать без аргументов.
