You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 21:47:32