Python

atexit — 종료 처리기


atexit 모듈은 정리 함수를 등록하고 해제하는 함수를 정의합니다. 이렇게 등록된 함수는 정상적인 인터프리터 종료 시 자동으로 실행됩니다. atexit`는 함수들을 등록된 *역순* 으로 실행합니다. 만약 ``A`, B, C 를 등록한다면, 인터프리터 종료 시에는 C, B, A 순서로 실행됩니다.

참고: 이 모듈을 통해 등록된 함수는 다음과 같은 경우 호출되지 않습니다. 프로그램이 파이썬이 처리하지 않는 시그널에 의해 종료될 때. 파이썬의 치명적인 내부 에러가 감지되었을 때. os._exit() 가 호출될 때.

참고: 정리 함수 내에서 함수를 등록하거나 등록을 해제하는 효과는 정의되지 않습니다.

버전 3.7에서 변경: C-API 서브 인터프리터와 함께 사용될 때, 등록된 함수는 등록된 인터프리터에 국지적입니다.

atexit.register(func, *args, **kwargs)

func 를 종료 시에 실행할 함수로 등록합니다. func 에 전달되어야 하는 선택적 인자는 register() 에 인자로 전달되어야 합니다. 같은 함수와 인자를 두 번 이상 등록 할 수 있습니다.

정상적인 프로그램 종료 시에 (예를 들어, sys.exit() 가 호출되거나 주 모듈의 실행이 완료된 경우에), 등록된 모든 함수는 후입선출 순서로 호출됩니다. 낮은 수준의 모듈은 일반적으로 상위 수준 모듈보다 먼저 임포트 되기 때문에 나중에 정리해야 한다는 가정입니다.

종료 처리기의 실행 중에 예외가 발생하면 (SystemExit가 발생하지 않는다면) 트레이스백이 인쇄되고 예외 정보가 저장됩니다. 모든 종료 처리기가 실행될 기회를 얻은 후에, 발생한 마지막 예외를 다시 일으킵니다.

이 함수는 func 을 반환하므로 데코레이터로 사용할 수 있습니다.

경고

등록된 함수에서 새 스레드를 시작하거나 os.fork`를 호출하면, Python 런타임 스레드가 스레드 상태를 해제하는 동안 내부 :mod:`threading() 루틴이나 새 프로세스가 해당 상태를 사용하려고 시도하면서 경쟁 상태가 발생할 수 있습니다. 이는 깨끗한 종료보다는 충돌을 일으킬 수 있습니다.

버전 3.12에서 변경: 등록된 함수에서 새 스레드를 시작하거나 :func:`os.fork`로 새 프로세스를 포크하려고 시도하면 이제 :exc:`RuntimeError`가 발생합니다.

atexit.unregister(func)

func 를 인터프리터 종료 시 실행할 함수 목록에서 제거합니다. unregister()func 가 이전에 등록되지 않은 경우 조용히 아무것도 하지 않습니다. func 가 두 번 이상 등록된 경우, atexit 호출 스택의 해당 함수의 모든 발생 건이 제거됩니다. 등록을 해제하는 동안 내부적으로 동등 비교(==)가 사용되므로, 함수 참조는 일치하는 아이덴티티를 가질 필요가 없습니다.

더 보기

모듈 readline

atexit`을 사용하여 :mod:`readline 히스토리 파일을 읽고 쓰는 유용한 예제입니다.

atexit 예제

다음의 간단한 예제는, 모듈이 임포트 될 때 파일에서 카운터를 읽고 프로그램이 종료할 때 프로그램의 명시적인 호출에 의존하지 않고 카운터의 변경된 값을 자동으로 저장하는 방법을 보여줍니다.:

try:
    with open('counterfile') as infile:
        _count = int(infile.read())
except FileNotFoundError:
    _count = 0

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

def savecounter():
    with open('counterfile', 'w') as outfile:
        outfile.write('%d' % _count)

import atexit

atexit.register(savecounter)

위치 및 키워드 인자가 등록된 함수가 호출될 때 전달되도록 register() 에 전달할 수 있습니다:

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

import atexit

atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')

데코레이터 로 사용하기:

import atexit

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

이 방법은 인자 없이 호출할 수 있는 함수에서만 작동합니다.