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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20576960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:45:34  来源:igfitidea点击:

Python - Infinite while loop, break on user input

pythonwhile-loopuser-input

提问by TehTechGuy

I have an infinite while loop that I want to break out of when the user presses a key. Usually I use raw_inputto get the user's response; however, I need raw_inputto not wait for the response. I want something like this:

我有一个无限的 while 循环,我想在用户按下某个键时跳出它。通常我raw_input用来获取用户的响应;但是,我不需要raw_input等待响应。我想要这样的东西:

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

This should be a simple, but I can't seem to figure it out. I'm leaning towards a solution using threading, but I would rather not have to do that. How can I accomplish this?

这应该是一个简单的,但我似乎无法弄清楚。我倾向于使用线程的解决方案,但我宁愿不必这样做。我怎样才能做到这一点?

采纳答案by octref

I think you can do better with msvcrt:

我认为你可以用 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)

Sadly, still windows-specific.

可悲的是,仍然是特定于 Windows 的。

回答by TehTechGuy

Using the msvcrtmodule as thebjornrecommended I was able to come up with something that works. The following is a basic example that will exit the loop if any key is pressed, not just enter.

使用thebjorn推荐的msvcrt模块,我能够想出一些有用的东西。以下是一个基本示例,如果按下任何键,则将退出循环,而不仅仅是输入。

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

回答by micromoses

You can use non-blocking read from stdin:

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

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)

回答by moisesvega

What you need is a non-blocking raw input, if you don't want to use threads there is a simple solution like this one below where he is doing a timeout of 20 ms and then raise and exception if the user doesn't press a key, if he does then the class returns the key pressed.

你需要的是一个非阻塞的原始输入,如果你不想使用线程,那么有一个像下面这样的简单解决方案,他正在做 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 ''

Source code

源代码

回答by gtcoder

On python 3.5 you can use the following code. It can be adjusted for a specific keystroke. The while loop will keep running until the user presses a key.

在 python 3.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()

回答by pratyay

I could not get some of the popular answers working. So I came up with another approach using the CTRL+ Cto plug in user input and imbibe a keyboard interrupt. A simple solution can be using a try-catch block,

我无法得到一些流行的答案。所以我想出了另一种方法,使用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...

I got this idea from running a number of servers like flask and django. This might be slightly different from what the OP asked, but it might help someone else who wanted a similar thing.

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