卡在用户输入时跳出 while 循环
Break out of a while loop while stuck on user input
我有以下代码来获取用户输入以执行某些任务。我想要的是在完成此模块之外的某些其他任务时跳出用户提示。因此,即使 shell 显示 'Enter Command:',我也希望它停止等待用户的提示并继续执行其他任务。这甚至可能吗?如果可能的话,怎么办?提前致谢。
def get_user_input():
while True:
info = str(raw_input('Enter Command:'))
if info == 'exit':
break
if info == 'do_something':
do_something()
编辑:
实际上这已经在线程中并且线程正确关闭。问题是屏幕卡在用户提示上,即使此时用户提示无用,因为调用输入的线程已经关闭。有什么建议吗?
使用信号
您可以使用 signal 模块(linux / 仅限 unix)
import signal
class UserInputTimeoutError(Exception):
pass
def handler(signum, frame):
raise UserInputTimeoutError('no input from user')
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
# This may hang indefinitely
user_input = raw_input('please insert something here:')
print('got %s from user' % user_input)
# cancel the alarm signal
signal.alarm(0)
except UserInputTimeoutError:
print('\nno input from user')
输入为'hello'时的输出:
please insert something here:hello
got hello from user
5秒无输入输出:
please insert something here:
no input from user
使用Select
另一种选择是使用 select.select()
进行 non-blocking io 操作。
get_user_input
函数尝试每 0.1 秒读取一次 sys.stdin,如果有数据要读取,它会读取单个字节。如果遇到新行,它 returns 字符串。
如果超时过去我们退出返回None
代码:
import select
import sys
import time
def get_user_input(msg, timeout=5):
print(msg)
user_input = []
stime = time.time()
while time.time() - stime <= timeout:
readables, _, _ = select.select([sys.stdin], [], [], 0.1)
if not readables:
continue
chr = readables[0].read(1)
if chr == '\n':
return ''.join(user_input)
user_input.append(chr)
user_input = get_user_input('please insert something:')
if user_input is None:
print('no user input')
else:
print('input is %s' % user_input)
输入的示例输出 hello select
:
please insert something:
hello select
input is hello select
5秒无输入示例:
please insert something:
no user input
Windows支持
如果您出于某种原因使用 windows,您可以查看此 answer about msvcrt
模块。
基本上它与 select.select
相同,用于 non-blocking io 使用 msvcrt.kbhit()
检查用户是否返回输入。
如果您需要更多信息,请更新您的 OS。
我认为您可以使用此答案读取直到超时,然后检查变量并在变量设置为 false 时退出。如果没有,则尝试再次阅读。
import sys, select
print "Answer me!"
while var:
i, o, e = select.select( [sys.stdin], [], [], 10 )
if (i):
print "You said", sys.stdin.readline().strip()
break
我有以下代码来获取用户输入以执行某些任务。我想要的是在完成此模块之外的某些其他任务时跳出用户提示。因此,即使 shell 显示 'Enter Command:',我也希望它停止等待用户的提示并继续执行其他任务。这甚至可能吗?如果可能的话,怎么办?提前致谢。
def get_user_input():
while True:
info = str(raw_input('Enter Command:'))
if info == 'exit':
break
if info == 'do_something':
do_something()
编辑: 实际上这已经在线程中并且线程正确关闭。问题是屏幕卡在用户提示上,即使此时用户提示无用,因为调用输入的线程已经关闭。有什么建议吗?
使用信号
您可以使用 signal 模块(linux / 仅限 unix)
import signal
class UserInputTimeoutError(Exception):
pass
def handler(signum, frame):
raise UserInputTimeoutError('no input from user')
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
# This may hang indefinitely
user_input = raw_input('please insert something here:')
print('got %s from user' % user_input)
# cancel the alarm signal
signal.alarm(0)
except UserInputTimeoutError:
print('\nno input from user')
输入为'hello'时的输出:
please insert something here:hello
got hello from user
5秒无输入输出:
please insert something here:
no input from user
使用Select
另一种选择是使用 select.select()
进行 non-blocking io 操作。
get_user_input
函数尝试每 0.1 秒读取一次 sys.stdin,如果有数据要读取,它会读取单个字节。如果遇到新行,它 returns 字符串。
如果超时过去我们退出返回None
代码:
import select
import sys
import time
def get_user_input(msg, timeout=5):
print(msg)
user_input = []
stime = time.time()
while time.time() - stime <= timeout:
readables, _, _ = select.select([sys.stdin], [], [], 0.1)
if not readables:
continue
chr = readables[0].read(1)
if chr == '\n':
return ''.join(user_input)
user_input.append(chr)
user_input = get_user_input('please insert something:')
if user_input is None:
print('no user input')
else:
print('input is %s' % user_input)
输入的示例输出 hello select
:
please insert something:
hello select
input is hello select
5秒无输入示例:
please insert something:
no user input
Windows支持
如果您出于某种原因使用 windows,您可以查看此 answer about msvcrt
模块。
基本上它与 select.select
相同,用于 non-blocking io 使用 msvcrt.kbhit()
检查用户是否返回输入。
如果您需要更多信息,请更新您的 OS。
我认为您可以使用此答案读取直到超时,然后检查变量并在变量设置为 false 时退出。如果没有,则尝试再次阅读。
import sys, select
print "Answer me!"
while var:
i, o, e = select.select( [sys.stdin], [], [], 10 )
if (i):
print "You said", sys.stdin.readline().strip()
break