📜  python 输入超时 - Python (1)

📅  最后修改于: 2023-12-03 14:46:18.884000             🧑  作者: Mango

Python 输入超时

在编写 Python 程序时,有时需要限制用户输入的时间,防止程序因输入等待时间过长而出现“假死”现象,或者是需要在一定时间内完成用户输入后立即执行后续操作,这时就需要使用输入超时功能。

Python 提供了多种方法实现输入超时,以下介绍常见的三种方法。

1. signal.alarm()

signal.alarm() 函数可以用来设置一个定时器,在给定时间后给当前进程发送信号。在 Python 中,默认处理信号是中断程序并抛出 KeyboardInterrupt 异常,在这里我们可以自定义信号处理函数。代码如下:

import signal

def time_out_handler(signum, frame):
    print('Time Out!')

signal.signal(signal.SIGALRM, time_out_handler)  # 注册信号处理函数

signal.alarm(5)  # 设置超时时间

try:
    # 等待用户输入
    input_str = input('Please input something: ')

    # 取消定时器
    signal.alarm(0)

    print('You have entered:', input_str)

except KeyboardInterrupt:
    # 取消定时器
    signal.alarm(0)
    print('Interrupted by user')

首先声明了一个异步信号处理函数 time_out_handler(),可以在其中定义我们自己的信号处理行为。然后利用 signal.signal() 函数为 SIGALRM 信号注册了信号处理函数,以便在超时时得到通知。

接下来是重点,我们使用定时器 signal.alarm() 函数设置了一个5秒钟的超时时间。如果等待时间超过5秒钟,将会以 SIGALRM 信号的形式中断程序,并执行 time_out_handler() 函数中的操作。

在使用超时功能的时候,一定要设置信号处理程序,否则程序会直接退出并显示 Alarm clock(死亡信号)信息。

2. select.select()

select.select() 函数可以在指定的读写描述符上等待读写事件,而且可以指定超时时间。类似于套接字等待组播数据包或单播数据包等场景。代码如下:

import sys
import select

timeout = 5  # 超时时间
sys.stdout.write('Please input something: ')
sys.stdout.flush()  # 刷新输出缓冲区

inputs, _, _ = select.select([sys.stdin], [], [], timeout)

if not inputs:
    print('Time Out!')
else:
    data = sys.stdin.readline().rstrip('\n')
    print('You have entered:', data)

首先是定义了一个超时时间 timeout,然后通过 select.select() 函数监听标准输入 sys.stdin,并等待读事件。如果在给定时间内没有读取到输入数据,则超时并返回空列表。

如果有数据可读,则读取输入并去掉行末的换行符,打印用户输入的内容。

3. threading.Timer()

使用 threading.Timer() 函数也可以实现输入超时。这个函数可以在指定时间后执行一个函数。代码如下:

import threading

def input_with_timeout(prompt, timeout):
    print(prompt)
    sys.stdout.flush()

    timer = threading.Timer(timeout, lambda: print('\nTime Out!'))
    astring = None
    try:
        timer.start()
        astring = input()
    finally:
        timer.cancel()

    if astring is not None:
        print('You have entered:', astring)

首先定义了一个异步定时器函数,当定时器时间到达时,异步执行 lambda 表达式中的操作,这里只是输出一个超时信息。然后利用 try-finally 语句保证程序中断时一定要取消定时器,否则程序会报异常。

在主函数中,首先输出提示信息,然后异步启动一个定时器任务,等待用户输入。如果在指定时间内未等到用户输入,则会执行 timeout 操作,否则会输出用户输入的内容。

总结:以上介绍了三种 Python 实现输入超时的方法,分别是使用 signal.alarm()select.select() ,以及 threading.Timer() 函数。读者可以根据具体需要,选择相应的超时方式来作为自己程序的一部分。