Iterating by standard in blocks until EOF is read

I have two scripts that are connected by a Unix pipe. The first script writes lines to standard and they are consumed by the second script.

Consider the following

# producer.py
import sys
import time
for x in range(10):
    sys.stdout.write("thing number %d\n"%x)
    sys.stdout.flush()
    time.sleep(1)

      

and

# consumer.py
import sys
for line in sys.stdin:
    print line

      

Now when I run:, python producer.py | python consumer.py

I expect to see a new line of output every second. Instead, I wait 10 seconds and I see the entire output at once.

Why can't I iterate stdin

over one element at a time? Why do I have to wait until producer

it gives me EOF

before the loop is started?

Note that I can change to the correct behavior by changing consumer.py

to:

# consumer.py
import sys    
def stream_stdin():
    line = sys.stdin.readline()
    while line:
        yield line
        line = sys.stdin.readline()

for line in stream_stdin():
    print line

      

I am wondering why I have to explicitly create a generator for a stream of items stdin

. Why isn't this happening implicitly?

+3


source to share


1 answer


As per the help message python -h

:



-u Force stdin, stdout and stderr must not be fully loaded. On systems where this matters, also set stdin, stdout, and stderr to binary mode. Note: Internal buffering in xread-lines (), readlines () and file object iterators ("for a line in sys.stdin"), which is not affected by this option. around this you will want to use "sys.stdin.readline ()" inside a "while 1:".

+2


source







All Articles