def init(self):
self.text = '' # empty string when created
def write(self, string): # add a string of bytes
self.text += string
def writelines(self, lines): # add each line in a list
for line in lines: self.write(line)
class Input: # simulated input file
def init(self, input=''): # default argument
self.text = input # save string when created
def read(self, size=None): # optional argument
if size == None: # read N bytes, or all
res, self.text = self.text, ''
else:
res, self.text = self.text[:size], self.text[size:]
return res
def readline(self):
eoln = self.text.find('\n') # find offset of next eoln
if eoln == −1: # slice off through eoln
res, self.text = self.text, ''
else:
res, self.text = self.text[:eoln+1], self.text[eoln+1:]
return res
def redirect(function, pargs, kargs, input): # redirect stdin/out
savestreams = sys.stdin, sys.stdout # run a function object
sys.stdin = Input(input) # return stdout text
sys.stdout = Output()
try:
result = function(*pargs, **kargs) # run function with args
output = sys.stdout.text
finally:
sys.stdin, sys.stdout = savestreams # restore if exc or not
return (result, output) # return result if no exc
This module defines two classes that masquerade as real files:
Output
Provides the write method interface (a.k.a. protocol) expected of output files but
saves all output in an in-memory string as it is written.
Input
Provides the interface expected of input files, but provides input on demand from
an in-memory string passed in at object construction time.
The redirect function at the bottom of this file combines these two objects to run a
single function with input and output redirected entirely to Python class objects. The
passed-in function to run need not know or care that its print and input function calls
and stdin and stdout method calls are talking to a class rather than to a real file, pipe,
or user.
To demonstrate, import and run the interact function at the heart of the test
streams script of Example 3-5 that we’ve been running from the shell (to use the
124 | Chapter 3: Script Execution Context