Python-无限while循环,在用户输入时中断

Python-无限while循环,在用户输入时中断,python,while-loop,user-input,Python,While Loop,User Input,我有一个无限的while循环,当用户按下一个键时,我想打破这个循环。通常我使用raw_input获取用户的响应;但是,我需要raw_input不等待响应。我想要这样的东西: print 'Press enter to continue.' while True: # Do stuff # # User pressed enter, break out of loop 这应该是一个简单的问题,但我似乎不明白。我倾向于使用线程的解决方案,但我宁愿不这样做。如何才能做到这一点

我有一个无限的while循环,当用户按下一个键时,我想打破这个循环。通常我使用
raw_input
获取用户的响应;但是,我需要
raw_input
不等待响应。我想要这样的东西:

print 'Press enter to continue.'
while True:
    # Do stuff
    #
    # User pressed enter, break out of loop

这应该是一个简单的问题,但我似乎不明白。我倾向于使用线程的解决方案,但我宁愿不这样做。如何才能做到这一点?

按照建议使用
msvcrt
模块,我能够想出一些可行的方法。下面是一个基本示例,如果按下任何键,都将退出循环,而不仅仅是回车

import msvcrt, time
i = 0
while True:
    i = i + 1
    if msvcrt.kbhit():
        break
    time.sleep(0.1)
print i

您可以使用标准输入的非阻塞读取:

import sys
import os
import fcntl
import time

fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)
while True:
    print("Waiting for user input")
    try:
        stdin = sys.stdin.read()
        if "\n" in stdin or "\r" in stdin:
            break
    except IOError:
        pass
    time.sleep(1)

您需要的是一个非阻塞的原始输入,如果您不想使用线程,下面有一个简单的解决方案,他将超时20毫秒,然后引发异常,如果用户不按某个键,则类返回按下的键

import signal

class AlarmException(Exception):
    pass

def alarmHandler(signum, frame):
    raise AlarmException

def nonBlockingRawInput(prompt='', timeout=20):
    signal.signal(signal.SIGALRM, alarmHandler)
    signal.alarm(timeout)
    try:
        text = raw_input(prompt)
        signal.alarm(0)
        return text
    except AlarmException:
        print '\nPrompt timeout. Continuing...'
    signal.signal(signal.SIGALRM, signal.SIG_IGN)
    return ''

我认为使用msvcrt可以做得更好:

import msvcrt, time
i = 0
while True:
    i = i + 1
    if msvcrt.kbhit():
        if msvcrt.getwche() == '\r':
            break
    time.sleep(0.1)
print(i)

遗憾的是,仍然是特定于windows的。

在Python3.5上,您可以使用以下代码。它可以针对特定的击键进行调整。while循环将一直运行,直到用户按键

import time
import threading

# set global variable flag
flag = 1

def normal():
    global flag
    while flag==1:
        print('normal stuff')
        time.sleep(2)
        if flag==False:
            print('The while loop is now closing')


def get_input():
    global flag
    keystrk=input('Press a key \n')
    # thread doesn't continue until key is pressed
    print('You pressed: ', keystrk)
    flag=False
    print('flag is now:', flag)

n=threading.Thread(target=normal)
i=threading.Thread(target=get_input)
n.start()
i.start()

我无法得到一些流行的答案。因此,我想出了另一种方法,使用
CTRL
+
C
插入用户输入并吸收键盘中断。一个简单的解决方案是使用try-catch块

i = 0
try:
    while True:
        i+=1
        print(i)
        sleep(1)
except:
    pass
# do what you want to do after it...

我是从运行许多服务器(如flask和django)中得到这个想法的。这可能与OP的要求略有不同,但它可能会帮助其他想要类似东西的人

我定义了一个函数,该函数要求用户输入数字并返回该数字的阶乘。如果用户想要停止,他们必须按0,然后它将退出循环。我们可以指定输入'n'的任何特定键以退出循环

import math

def factorial_func(n):

    return math.factorial(n)

while True:
    n = int(input("Please enter the number to find factorial: "))
    print(factorial_func(n))
    if n == 0:
       exit()

此线程可能有帮助(包含一个使用诅咒的工作示例):侦听事件?在
msvcrt
模块中有Windows特定的方法来执行此操作。@alKid,不完全是。我正在记录一些由用户手动启动和结束的数据。这是目前无法从我的脚本中控制的东西。该线程还链接到一个可能适用的配方:应该注意的是,您的答案是特定于Unix的。我个人使用Windows,但这段代码仍然很好。