developer tip

try-except없이 Python에서 keyboardinterrupt 캡처

copycodes 2020. 8. 20. 19:00
반응형

try-except없이 Python에서 keyboardinterrupt 캡처


파이썬에서 KeyboardInterrupt모든 코드를 try- except안에 넣지 않고 이벤트 를 캡처하는 방법이 있습니까?

사용자가 Ctrl+를 누르면 흔적없이 깔끔하게 종료하고 싶습니다 C.


예, 모듈 신호를 사용하여 인터럽트 핸들러를 설치 하고 threading.Event를 사용하여 영원히 기다릴 수 있습니다 .

import signal
import sys
import time
import threading

def signal_handler(signal, frame):
    print('You pressed Ctrl+C!')
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
forever = threading.Event()
forever.wait()

트레이스 백을 표시하지 않으려면 다음과 같이 코드를 작성하십시오.

## all your app logic here
def main():
   ## whatever your app does.


if __name__ == "__main__":
   try:
      main()
   except KeyboardInterrupt:
      # do nothing here
      pass

(예, 이것이 질문에 직접 대답하지 않는다는 것을 알고 있지만 try / except 블록이 왜 필요한지에 대한 이유는 명확하지 않습니다.


자체 시그널 핸들러를 설정하는 대안은 컨텍스트 관리자를 사용하여 예외를 포착하고 무시하는 것입니다.

>>> class CleanExit(object):
...     def __enter__(self):
...             return self
...     def __exit__(self, exc_type, exc_value, exc_tb):
...             if exc_type is KeyboardInterrupt:
...                     return True
...             return exc_type is None
... 
>>> with CleanExit():
...     input()    #just to test it
... 
>>>

이것은 무슨 일이 일어나고 있는지에 대한 명시적인 언급을 유지하면서 try- except블록을 제거합니다 .

또한 매번 신호 처리기를 다시 설정하고 재설정 할 필요없이 코드의 일부 부분에서만 인터럽트를 무시할 수 있습니다.


나는 이것이 오래된 질문이라는 것을 알고 있지만 먼저 여기에 와서 atexit모듈 을 발견했습니다 . 아직 크로스 플랫폼 실적이나주의 사항 전체 목록에 대해 알지 못하지만 지금까지 KeyboardInterruptLinux에서 사후 정리 를 처리 할 때 찾던 바로 그 내용 입니다. 문제에 접근하는 다른 방법을 던지고 싶었습니다.

I want to do post-exit clean-up in the context of Fabric operations, so wrapping everything in try/except wasn't an option for me either. I feel like atexit may be a good fit in such a situation, where your code is not at the top level of control flow.

atexit is very capable and readable out of the box, for example:

import atexit

def goodbye():
    print "You are now leaving the Python sector."

atexit.register(goodbye)

You can also use it as a decorator (as of 2.6; this example is from the docs):

import atexit

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

If you wanted to make it specific to KeyboardInterrupt only, another person's answer to this question is probably better.

But note that the atexit module is only ~70 lines of code and it would not be hard to create a similar version that treats exceptions differently, for example passing the exceptions as arguments to the callback functions. (The limitation of atexit that would warrant a modified version: currently I can't conceive of a way for the exit-callback-functions to know about the exceptions; the atexit handler catches the exception, calls your callback(s), then re-raises that exception. But you could do this differently.)

For more info see:


You can prevent printing a stack trace for KeyboardInterrupt, without try: ... except KeyboardInterrupt: pass (the most obvious and propably "best" solution, but you already know it and asked for something else) by replacing sys.excepthook. Something like

def custom_excepthook(type, value, traceback):
    if type is KeyboardInterrupt:
        return # do nothing
    else:
        sys.__excepthook__(type, value, traceback)

참고URL : https://stackoverflow.com/questions/4205317/capture-keyboardinterrupt-in-python-without-try-except

반응형