Python捕获KeyboardInterrupt触发can't re-enter readline错误求助
问题:捕获KeyboardInterrupt后调用input()触发RuntimeError
我编写了一个需要获取用户输入的脚本,希望捕获KeyboardInterrupt异常,让脚本显示提示并要求用户按回车键终止运行。参考相关代码实现后,在捕获异常后调用input()时,Python返回错误:RuntimeError: can't re-enter readline,目前只能采用等待5秒后退出的替代方案,找不到问题根源。
复现代码
requestKey = "Press Enter key to exit...\n" exitTimeout = "\n\nstop received! exit in 5 seconds...\n" import sys, signal, threading, time # 捕获SIGINT信号的处理函数 def exitKey(signal, frame): # print(exitTimeout) # time.sleep(5) input(requestKey) sys.exit() signal.signal(signal.SIGINT, exitKey) watchExit = threading.Event() while True: userInput = input("\nenter something: ") print("user input: " + userInput)
错误示例
enter something: ^CTraceback (most recent call last): File "/Users/user/Documents/signalError.py", line 17, in <module> userInput = input("\nenter something: ") File "/Users/user/Documents/signalError.py", line 10, in exitKey input(requestKey) RuntimeError: can't re-enter readline
解决方案
错误原因
这个错误的核心是:Python的readline模块不支持嵌套调用。当你按下Ctrl+C时,主程序正处于input()的阻塞状态(也就是正在调用readline等待用户输入),此时触发的信号处理函数里又调用input(),相当于嵌套调用了readline,直接触发RuntimeError。
方法一:用线程处理退出逻辑
把等待用户回车的逻辑放到独立线程中,信号处理函数只负责唤醒主程序的input阻塞,避免嵌套调用:
requestKey = "Press Enter key to exit...\n" import sys, signal, threading exit_flag = False def exit_prompt(): print(requestKey) input() sys.exit() def handle_sigint(signal, frame): global exit_flag exit_flag = True # 写入换行符唤醒被input阻塞的主线程 sys.stdin.write('\n') sys.stdin.flush() signal.signal(signal.SIGINT, handle_sigint) while True: if exit_flag: threading.Thread(target=exit_prompt, daemon=True).start() break try: userInput = input("\nenter something: ") print("user input: " + userInput) except EOFError: # 处理唤醒后产生的EOF异常 pass
方法二:直接用try-except捕获KeyboardInterrupt(更简单)
放弃信号处理,直接在主循环里捕获KeyboardInterrupt异常,此时主程序的input()已经退出,再调用input()就不会有嵌套问题:
requestKey = "Press Enter key to exit...\n" import sys while True: try: userInput = input("\nenter something: ") print("user input: " + userInput) except KeyboardInterrupt: print(requestKey) input() sys.exit()
这种方法逻辑更简洁,不需要处理线程和信号的复杂交互,是更推荐的方案。
内容的提问来源于stack exchange,提问作者noeXzTi
相关产品推荐
相关产品推荐

