Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-Blocking raw_input() in python

Tags:

python

After digging around in SO for a while, I still haven't found a good answer to what I would hope is a fairly common need. Basically I need a main thread to do "stuff" until it receives input and then act on that input, then return to the original "stuff". My problem every time seems to be that my program execution seems to halt completely at the raw input, whether I call it in a thread or anywhere else. Forwarning I'm pretty novice to python, but I'd hope this shouldn't be too nasty to implement. Here is what I'm playing with (pulled from my other question where my threading question was answered handily)

So I'm trying to write a program that looks for keyboard presses and then does something in the main program based upon what the user inputs. I'm trying to run the keyboard listening in a thread and then compare whats in the variable in my main loop, but I don't ever seem to be getting the threaded keyboard input. In the below code, the print maybe updating line never happens, just the else block from the main while loop. What do i need to do so that my main loop is aware of the keys pressed by the user?

import threading
import time

kbdInput = ''
playingID = ''

def kbdListener():
    global kbdInput
    kbdInput = rawInput()
    print "maybe updating...the kbdInput variable is: ",kbdInput

listener = threading.Thread(target=kbdListener)

while True:
    print "kbdInput: ",kbdInput
    print "playingID: ",playingID
    if playingID != kbdInput:
        print "Recieved new keyboard Input. Setting playing ID to keyboard input value"
        playingID = kbdInput
    else:
        print "No input from keyboard detected. Sleeping 2 seconds"
    time.sleep(2)
like image 676
MydKnight Avatar asked Jun 19 '15 03:06

MydKnight


People also ask

What does the Python raw_input () function do?

Python raw_input function is used to get the values from the user. We call this function to tell the program to stop and wait for the user to input the values.

What is raw_input () in Python give an example?

The raw_input() function reads a line from input (i.e. the user) and returns a string by stripping a trailing newline. This page shows some common and useful raw_input() examples for new users. Please note that raw_input() was renamed to input() in Python version 3.

What is the difference between input () and raw_input ()?

Basically, the difference between raw_input and input is that the return type of raw_input is always string, while the return type of input need not be string only. Python will judge as to what data type will it fit the best. In case you have entered a number, it will take it as an integer.

Why is raw_input not working in Python?

The NameError: name 'raw_input' is not defined error is raised when you try to use the raw_input() method in Python 3. To fix this error, replace all instances of raw_input() with the input() function in your program.


2 Answers

If you actually want to keep the while loop going on forever, you will need to create a new thread and start it, each time the old one has finished.

I updated the example in the question to make that work:

import threading
import time

kbdInput = ''
playingID = ''
finished = True

def kbdListener():
    global kbdInput, finished
    kbdInput = raw_input("> ")
    print "maybe updating...the kbdInput variable is: {}".format(kbdInput)
    finished = True

while True:
    print "kbdInput: {}".format(kbdInput)
    print "playingID: {}".format(playingID)
    if playingID != kbdInput:
        print "Received new keyboard Input. Setting playing ID to keyboard input value"
        playingID = kbdInput
    else:
        print "No input from keyboard detected. Sleeping 2 seconds"
    if finished:
        finished = False
        listener = threading.Thread(target=kbdListener)
        listener.start()
    time.sleep(2)
like image 92
Dirk van Oosterbosch Avatar answered Nov 07 '22 15:11

Dirk van Oosterbosch


You created a thread but forget to start it:

listener = threading.Thread(target=kbdListener)
listener.start()
like image 45
Tuan Anh Hoang-Vu Avatar answered Nov 07 '22 16:11

Tuan Anh Hoang-Vu