[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

The latter option may be more direct (and the redirection utility module also returns
the raw socket in support of such usage), but it isn’t viable in all scenarios, especially
for existing or multimode scripts. In many cases, it may be most straightforward to use
manual flush calls in shell-oriented programs whose streams might be linked to other
programs through sockets.


Buffering in other contexts: Command pipes revisited


Also keep in mind that buffered streams and deadlock are general issues that go beyond
socket wrapper files. We explored this topic in Chapter 5; as a quick review, the non-
socket Example 12-15 does not fully buffer its output when it is connected to a terminal
(output is only line buffered when run from a shell command prompt), but does if
connected to something else (including a socket or pipe).


Example 12-15. PP4E\Internet\Sockets\pipe-unbuff-writer.py


output line buffered (unbuffered) if stdout is a terminal, buffered by default for


other devices: use -u or sys.stdout.flush() to avoid delayed output on pipe/socket


import time, sys
for i in range(5):
print(time.asctime()) # print transfers per stream buffering
sys.stdout.write('spam\n') # ditto for direct stream file access
time.sleep(2) # unles sys.stdout reset to other file


Although text-mode files are required for Python 3.X’s print in general, the -u flag still
works in 3.X to suppress full output stream buffering. In Example 12-16, using this flag
makes the spawned script’s printed output appear every 2 seconds, as it is produced.
Not using this flag defers all output for 10 seconds, until the spawned script exits, unless
the spawned script calls sys.stdout.flush on each iteration.


Example 12-16. PP4E\Internet\Sockets\pipe-unbuff-reader.py


no output for 10 seconds unless Python -u flag used or sys.stdout.flush()


but writer's output appears here every 2 seconds when either option is used


import os
for line in os.popen('python -u pipe-unbuff-writer.py'): # iterator reads lines
print(line, end='') # blocks without -u!


Following is the reader script’s output; unlike the socket examples, it spawns the writer
automatically, so we don’t need separate windows to test. Recall from Chapter 5 that
os.popen also accepts a buffering argument much like socket.makefile, but it does not
apply to the spawned program’s stream, and so would not prevent output buffering in
this case.


C:\...\PP4E\Internet\Sockets> pipe-unbuff-reader.py
Wed Apr 07 09:32:28 2010
spam
Wed Apr 07 09:32:30 2010
spam

838 | Chapter 12: Network Scripting

Free download pdf