Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a list of files using with/as context manager

Tags:

Note: I am aware of the

with open('f1') as f1, open('f2') as f2:     ... 

syntax. This is a different question.


Given a list of strings file_names is there a way using with/as to open every file name in that using a single line. Something such as:

with [open(fn) for fn in file_names] as files:     # use the list of files 

which of course doesn't work as it attempts to use the context manager on a list. The length of the list may not be known until run-time, such as sys.argv[1:]

like image 303
Ryan Haining Avatar asked Oct 16 '13 19:10

Ryan Haining


People also ask

What does the context manager do when you are opening a file with using with?

A context manager usually takes care of setting up some resource, e.g. opening a connection, and automatically handles the clean up when we are done with it. Probably, the most common use case is opening a file. The code above will open the file and will keep it open until we are out of the with statement.

How do I open multiple files in Python?

To open multiple files using "with open" in Python, we can separate each file with a comma. We call open with 'r' to open foo. txt and bar.

What does the context manager do when you are opening a file using with Mcq?

Context managers allow you to allocate and release resources precisely when you want to. The most widely used example of context managers is the with statement. Suppose you have two related operations which you'd like to execute as a pair, with a block of code in between.

What is the use of the with context manager?

The with statement in Python is a quite useful tool for properly managing external resources in your programs. It allows you to take advantage of existing context managers to automatically handle the setup and teardown phases whenever you're dealing with external resources or with operations that require those phases.


2 Answers

If you have access to Python 3.3+, there is a special class designed exactly for this purpose: the ExitStack. It works just like you'd expect:

with contextlib.ExitStack() as stack:     files = [stack.enter_context(open(fname)) for fname in filenames]     # All opened files will automatically be closed at the end of     # the with statement, even if attempts to open files later     # in the list raise an exception 
like image 92
Henry Keiter Avatar answered Sep 28 '22 23:09

Henry Keiter


How about this?

class ListContext:     def __init__(self, l):         self.l = l      def __enter__(self):         for x in self.l:             x.__enter__()         return self.l      def __exit__(self, type, value, traceback):         for x in self.l:             x.__exit__(type, value, traceback)  arr = ['a', 'b', 'c']  with ListContext([open(fn, 'w') for fn in arr]) as files:     print files  print files 

Output is:

[<open file 'a', mode 'w' at 0x7f43d655e390>, <open file 'b', mode 'w' at 0x7f43d655e420>, <open file 'c', mode 'w' at 0x7f43d655e4b0>] [<closed file 'a', mode 'w' at 0x7f43d655e390>, <closed file 'b', mode 'w' at 0x7f43d655e420>, <closed file 'c', mode 'w' at 0x7f43d655e4b0>] 

Notice, they are open inside the with context and closed outside.

This is using the Python context manager API.

EDIT: It seems like this already exists but is deprecated: See contextlib and this SO question. Use it like this:

import contextlib  with contextlib.nested(*[open(fn, 'w') for fn in arr]) as files:     print files print files 
like image 43
Max Avatar answered Sep 29 '22 00:09

Max