Python - Infinite while loop, break on user input

前端 未结 6 1279
挽巷
挽巷 2020-12-01 22:14

I have an infinite while loop that I want to break out of when the user presses a key. Usually I use raw_input to get the user\'s response; however, I need

相关标签:
6条回答
  • 2020-12-01 22:20

    Using the msvcrt module as thebjorn recommended 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.

    import msvcrt, time
    i = 0
    while True:
        i = i + 1
        if msvcrt.kbhit():
            break
        time.sleep(0.1)
    print i
    
    0 讨论(0)
  • 2020-12-01 22:20

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

    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.

    0 讨论(0)
  • 2020-12-01 22:29

    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.

    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()
    
    0 讨论(0)
  • 2020-12-01 22:42

    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)
    
    0 讨论(0)
  • 2020-12-01 22:42

    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.

    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

    0 讨论(0)
  • 2020-12-01 22:44

    I think you can do better with 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.

    0 讨论(0)
提交回复
热议问题