Welcome, guest | Sign In | My Account | Store | Cart

The pattern using with together with open() to automatically close a file after leaving the context is well known. To open a fixed number you can simply nest these statements or use the comma notation. For having a context which represents an arbitrary number of open files you can use the ExitStack class, but only for Python 3.3+.

For other Python versions I'm using the following class which I named Files. The presented implementation is only for reading files (for keeping it clear). Extending it for having various file modes should not pose a problem.

Python, 18 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Files(tuple):
  def __new__(cls, *filePaths):
    files = []
    try:
      for filePath in filePaths:
        files.append(open(filePath))
        files[-1].__enter__()
    except:
      for file in files:
        file.close()
      raise
    else:
      return super(Files, cls).__new__(cls, files)
  def __enter__(self):
    return self
  def __exit__(self, *args):
    for file in self:
      file.close()

A typical use looks like this:

with Files('.bashrc', '.profile') as (a, b):
    print a.read()
    print b.read()

Or, more complex: This mixes the contents of the given files in a round-robin fashion and continues reading from them like tail -f afterwards (useful to keep an eye on several growing logfiles at once). This will terminate as soon as in one file a line starting with END appears.

filePaths = argv[1:]
with Files(*filePaths) as files:
    while True:
        filesExhausted = True
        for file in files:
            line = file.readline()
            if line is not None:
                filesExhausted = False
                sys.stdout.write(line)
                if line.startswith('END'):
                    return  # or whatever leaves the outer loop
        if filesExhausted:
            time.sleep(1.0)
Created by Alfe on Mon, 13 Mar 2017 (MIT)
Python recipes (4591)
Alfe's recipes (12)

Required Modules

  • (none specified)

Other Information and Tasks