bestsource

Try-except 없이 Python에서 키보드 인터럽트

bestsource 2023. 9. 1. 21:12
반응형

Try-except 없이 Python에서 키보드 인터럽트

파이썬에서 캡처할 수 있는 방법이 있습니까?KeyboardInterrupt모든 코드를 a 안에 넣지 않은 이벤트try-except진술서?

사용자가 C+를 누르면 트레이스 없이 깨끗하게 종료하고 싶습니다.

예, 모듈 신호를 사용하여 인터럽트 핸들러를 설치하고 스레드를 사용하여 계속 기다릴 수 있습니다.이벤트:

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

(네, 이것이 질문에 직접적으로 대답하지 않는다는 것은 알고 있지만, 시도가 필요한 이유가 명확하지 않습니다./차단이 불쾌하다는 것을 제외하고는 -- 아마도 이것이 OP에게 덜 성가시게 만들 것입니다.)

자체 신호 처리기를 설정하는 대신 컨텍스트 관리자를 사용하여 예외를 탐지하고 무시하는 방법이 있습니다.

>>> 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에서 정리합니다.그 문제에 접근하는 다른 방법을 찾고 싶었을 뿐입니다.

패브릭 운영의 맥락에서 종료 후 청소를 수행하고 싶으므로 모든 것을 포장합니다.try/except나에게도 선택의 여지가 없었습니다.난 기분이…atexit코드가 제어 흐름의 최상위 수준에 있지 않은 경우에 적합할 수 있습니다.

atexit다음과 같은 기능이 매우 뛰어나고 즉시 읽을 수 있습니다.

import atexit

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

atexit.register(goodbye)

2.6 기준으로 이 문서를 장식자로 사용할 수도 있습니다.

import atexit

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

당신이 그것을 구체적으로 만들고 싶다면.KeyboardInterrupt단지, 이 질문에 대한 다른 사람의 대답이 아마도 더 나을 것입니다.

하지만 주의할 점은atexit모듈은 코드의 ~70줄에 불과하며 예외를 다르게 처리하는 유사한 버전을 만드는 것은 어렵지 않을 것입니다. 예를 들어 예외를 콜백 함수의 인수로 전달하는 것과 같습니다.(의 제한 사항:atexit수정된 버전을 보장할 수 있습니다. 현재 종료 콜백 함수가 예외에 대해 알 수 있는 방법을 생각할 수 없습니다.atexit핸들러가 예외를 포착하고 콜백을 호출한 다음 해당 예외를 다시 실행합니다.하지만 다르게 할 수도 있습니다.)

자세한 내용은 다음을 참조하십시오.

다음에 대한 스택 추적 인쇄를 방지할 수 있습니다.KeyboardInterrupt를 제외하고, 이없.try: ... except KeyboardInterrupt: pass(가장 분명하고 "최고의" 해결책이지만, 당신은 이미 알고 있고 다른 것을 요구했습니다.) 대체함으로써.

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

저는 모두가 제안한 해결책을 시도했지만, 실제로 작동하기 위해서는 코드를 즉흥적으로 수정해야 했습니다.다음은 제가 즉흥적으로 만든 코드입니다.

import signal
import sys
import time

def signal_handler(signal, frame):
    print('You pressed Ctrl+C!')
    print(signal) # Value is 2 for CTRL + C
    print(frame) # Where your execution of program is at moment - the Line Number
    sys.exit(0)

#Assign Handler Function
signal.signal(signal.SIGINT, signal_handler)

# Simple Time Loop of 5 Seconds
secondsCount = 5
print('Press Ctrl+C in next '+str(secondsCount))
timeLoopRun = True 
while timeLoopRun:  
    time.sleep(1)
    if secondsCount < 1:
        timeLoopRun = False
    print('Closing in '+ str(secondsCount)+ ' seconds')
    secondsCount = secondsCount - 1

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

반응형