簡體   English   中英

Python - 無限循環,中斷用戶輸入

[英]Python - Infinite while loop, break on user input

我有一個無限的 while 循環,我想在用戶按下某個鍵時跳出它。 通常我使用raw_input來獲取用戶的響應; 但是,我需要raw_input來不等待響應。 我想要這樣的東西:

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

這應該是一個簡單的,但我似乎無法弄清楚。 我傾向於使用線程的解決方案,但我寧願不必這樣做。 我怎樣才能做到這一點?

您可以使用非阻塞從標准輸入讀取:

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)

我認為你可以用 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 的。

在 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()

你需要的是一個非阻塞的原始輸入,如果你不想使用線程,那么有一個像下面這樣的簡單解決方案,他正在做 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 ''

源代碼

使用thebjorn推薦的msvcrt模塊,我能夠想出一些可行的方法。 以下是一個基本示例,如果按下任何鍵,將退出循環,而不僅僅是輸入。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM