Reputation: 31
Question 1: I have a piece of code like this (Python2.7):
for line in sys.stdin.readlines():
print line
When I run this code, input a string in the terminal and press Enter key, nothing happens. 'print line' doesn't work. So I imagine there is buffer for sys.stdin.readlines(), but I wonder how does it work? Can I flush it so every time a line is given, 'print line' can be executed imeediatly?
Question2: What's the difference between these two lines:
for line in sys.stdin:
for line in sys.stdin.readline():
I found their behavior is a little different. If I use ctrl+D to terminate the input, I have to press ctrl+D twice in the first case before it's really terminated. While in the second case, only one ctrl+D is enough.
Upvotes: 3
Views: 3532
Reputation: 1735
CTRL-D sends the EOF
(end of file) control character to stdin in an interactive shell. Usually, you feed a file to the stdin of a process via redirection (e.g. myprogram < myfile
), but if you are interactively typing characters into stdin of a process, you need to tell it when to stop reading the "file" you are actively creating.
sys.stdin.readlines
waits for stdin to complete (via an EOF
control character), then conveniently splits the entire stdin contents (flushed) before the EOF
into a list of tokens delimited by newline characters. When you hit ENTER, you send a \n
character, which is rendered for you as a new line, but does NOT tell stdin to stop reading.
Regarding the other two lines, I think this might help:
Think of the sys.stdin
object as a file. When you EOF
, you save that file and then you are not allowed to edit it anymore because it leaves your hands and belongs to stdin. You can perform functions on that file, like readlines
, which is a convenient way to say "I want a list, and each element is a line in that file". Or, you can just read one line from it with readline
, in which case the for loop would be only iterating over the characters in that line.
Internally, the reference to sys.stdin
blocks execution until EOF
is received in sys.stdin
. Then it becomes a file-like object stored in memory with a read pointer pointing to the beginning.
When you call just readline
, the pointer reads until it hits a \n
character, returns to you what it just traversed over, and stays put, waiting for you to move it again. Calling readline
again will cause the pointer to move until the next \n
, if it exists, else EOF
.
readlines
is really telling the pointer to traverse all the way (\n
is functionally meaningless) from its current position (not necessarily beginning of file) until it sees EOF
.
Trying it out is the best way to learn.
To see this behavior in action, try making a file with 10 lines, then redirect it to the stdin of a python script that prints sys.stdin.readline
3 times, then print sys.stdin.readlines
. You'll see 3 lines printed out then a list containing 7 elements :)
Upvotes: 1