Книга: Practical Programming, Fourth Edition
Назад: Writing Files
Дальше: Writing Algorithms That Use t he File-Reading Techniques

Writing Example Calls Using StringIO

To follow the function design recipe, you need to write example calls. Writing these calls using real files would involve creating test files for each of the situations you want to demonstrate. This approach is fragile because it means that you can’t just give the program to someone—you need to remember to include the test files in case they want to try your function. It’s also not optimal because anyone trying to understand the function needs to open the input and output files.

Python provides a class, StringIO, in the io module, that can be used as a mock open file. That means that you can read from it using the regular file-reading techniques as if it were a real file. StringIO objects can be used anywhere TextIO objects are expected.

Here, let’s create a StringIO object containing the same information as file number_pairs.txt, and read the first line:

 >>>​​ ​​from​​ ​​io​​ ​​import​​ ​​StringIO
 >>>​​ ​​input_string​​ ​​=​​ ​​'1.3 3.4\n2 4.2\n-1 1\n'
 >>>​​ ​​infile​​ ​​=​​ ​​StringIO(input_string)
 >>>​​ ​​infile.readline()
 '1.3 3.4\n'

You can also write to StringIO objects as if they were files, and retrieve their contents as a string using the method getvalue:

 >>>​​ ​​from​​ ​​io​​ ​​import​​ ​​StringIO
 >>>​​ ​​outfile​​ ​​=​​ ​​StringIO()
 >>>​​ ​​outfile.write(​​'1.3 3.4 4.7\n'​​)
 12
 >>>​​ ​​outfile.write(​​'2 4.2 6.2\n'​​)
 10
 >>>​​ ​​outfile.write(​​'-1 1 0.0\n'​​)
 9
 >>>​​ ​​outfile.getvalue()
 '1.3 3.4 4.7\n2 4.2 6.2\n-1 1 0.0\n'

You can now provide example calls in your sum_number_pairs function. Notice that you need two backslashes inside the examples because they are part of the docstring (see ):

 from​ ​typing​ ​import​ TextIO
 from​ ​io​ ​import​ StringIO
 
 
 def​ ​sum_number_pairs​(input_file: TextIO, output_file: TextIO) -> None:
 """Read the data from input_file, which contains two floats per line
  separated by a space. output_file for writing and, for each line in
  input_file, write a line to output_file that contains the two floats from
  the corresponding line of input_file plus a space and the sum of the two
  floats.
 
  >>> infile = StringIO('1.3 3.4​​\\​​n2 4.2​​\\​​n-1 1​​\\​​n')
  >>> outfile = StringIO()
  >>> sum_number_pairs(infile, outfile)
  >>> outfile.getvalue()
  '1.3 3.4 4.7​​\\​​n2 4.2 6.2​​\\​​n-1 1 0.0​​\\​​n'
  """
 
 for​ number_pair ​in​ input_file:
  number_pair = number_pair.strip()
  operands = number_pair.split()
  total = float(operands[0]) + float(operands[1])
  new_line = f​'{number_pair} {total}​​\n​​'
  output_file.write(new_line)
 if​ __name__ == ​'__main__'​:
 with​ open(​'number_pairs.txt'​, ​'r'​) ​as​ input_file, \
  open(​'number_pair_sums.txt'​, ​'w'​) ​as​ output_file:
  sum_number_pairs(input_file, output_file)
Назад: Writing Files
Дальше: Writing Algorithms That Use t he File-Reading Techniques