If I read input from stdin in python, the for loop will collect a number of lines before the body of the loop is run (at least in cpython).
from __future__ import print_function
import sys
for line in sys.stdin:
print("Echo:", line.strip())
Outputs:
$ python ../test.py
foo
bar
Echo: foo
Echo: bar
Lines are handled in some kind of batches. I can avoid it like this:
from __future__ import print_function
import sys
for line in iter(sys.stdin.readline, ''):
print("Echo:", line.strip())
Outputs:
$ python ../test.py
foo
Echo: foo
bar
Echo: bar
Which is what I need.
My problem is that I have to read utf-8 input and trick with iter() does not work with codecs.getwriter.
from __future__ import print_function
import sys
import codecs
sys.stdin = codecs.getreader('utf-8')(sys.stdin)
for line in iter(sys.stdin.readline, ''):
print("Echo:", line.strip())
$ python ../test.py
foo
bar
Echo: foo
Echo: bar
Is there any way to avoid this batching while reading utf8 data from stdin?
Edit: Added import statements for completeness.
Using lambda:
for line in iter(lambda: sys.stdin.readline().decode('utf-8'), ''):
print 'Echo:', line.strip()
or, decoding in loop body:
for line in iter(sys.stdin.readline, ''):
print "Echo:", line.decode('utf-8').strip()
You should probably use raw_input to get a line of input from stdin.
try:
while True:
print("Echo:", raw_input())
except EOFError:
pass
The problem is that Python 2 just has this kind of buffering. See the documentation for -u on the manpage
-u Force stdin, stdout and stderr to be totally unbuffered. On systems
where it matters, also put stdin, stdout and stderr in binary mode.
Note that there is internal buffering in xreadlines(), readlines() and
file-object iterators ("for line in sys.stdin") which is not influenced
by this option. To work around this, you will want to use
"sys.stdin.readline()" inside a "while 1:" loop.
The important part is that using sys.stdin.readline() is the recommended course of action; it's unlikely that there's a good way to forcibly unbuffer file objects.
You should just decode each line as you get it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With