简体   繁体   中英

What's behind sys.stdin.readlines()

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.

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 (eg 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.

What's going on behind the scenes?

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 .

Try it out!

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM