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