6

I'm trying to write a simple Python IRC client. So far I can read data, and I can send data back to the client if it automated. I'm getting the data in a while True, which means that I cannot enter text while at the same time reading data. How can I enter text in the console, that only gets sent when I press enter, while at the same time running an infinite loop?

Basic code structure:

while True:
    read data
    #here is where I want to write data only if it contains '/r' in it
Shef
  • 1,044
  • 1
  • 12
  • 19
  • 1
    Not sure what you are trying to do, but *threading* could be useful. – Christian Tapia Jun 02 '14 at 17:55
  • I basically want to be able to enter text into the console while also reading data from an infinite loop. – Shef Jun 02 '14 at 17:55
  • 5
    One thread should wait for user input and copy it to a thread-safe object (probably a queue) when new data is available. Other thread polls the safe object and processes new data if available. – heltonbiker Jun 02 '14 at 17:57
  • Possible duplicate of [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – ruohola May 04 '19 at 14:20

3 Answers3

5

Another way to do it involves threads.

import threading

# define a thread which takes input
class InputThread(threading.Thread):
    def __init__(self):
        super(InputThread, self).__init__()
        self.daemon = True
        self.last_user_input = None

    def run(self):
        while True:
            self.last_user_input = input('input something: ')
            # do something based on the user input here
            # alternatively, let main do something with
            # self.last_user_input

# main
it = InputThread()
it.start()
while True:
    # do something  
    # do something with it.last_user_input if you feel like it
timgeb
  • 76,762
  • 20
  • 123
  • 145
  • `raw_input` would probably be correct. I think I can work with it. Thanks :) – Shef Jun 02 '14 at 22:15
  • @Shef Ah yes, my example code is Python3, you are probably using an older version which uses raw_input. – timgeb Jun 03 '14 at 09:43
3

What you need is an event loop of some kind.

In Python you have a few options to do that, pick one you like:

and so on, there are hundreds of frameworks for this, you could also use any of the GUI frameworks like tkinter or PyQt to get a main event loop.

As comments have said above, you can use threads and a few queues to handle this, or an event based loop, or coroutines or a bunch of other architectures. Depending on your target platforms one or the other might be best. For example on windows the console API is totally different to unix ptys. Especially if you later need stuff like colour output and so on, you might want to ask more specific questions.

schlenk
  • 7,002
  • 1
  • 25
  • 29
0

You can use a async library (see answer of schlenk) or use https://docs.python.org/2/library/select.html

This module provides access to the select() and poll() functions available in most operating systems, epoll() available on Linux 2.5+ and kqueue() available on most BSD. Note that on Windows, it only works for sockets; on other operating systems, it also works for other file types (in particular, on Unix, it works on pipes). It cannot be used on regular files to determine whether a file has grown since it was last read.

guettli
  • 25,042
  • 81
  • 346
  • 663
  • I should emphasize this specific limitation for Windows: `select()` doesn't work on the standard input unless the standard input is a socket (can be done, but highly unlikely). – André Caron Jun 02 '14 at 19:14