I want to open multiple files using a with
statement (so I get the benefit of the context manager) based on boolean flags which instruct whether my program should or should not actually open each file.
I know I can use a with
statement to open multiple files, like:
with open('log.txt', 'w') as logfile, open('out_a.txt', 'w') as out_a, open('out_b.txt', 'w') as out_b:
# do something with logfile, out_a and out_b
# all files are closed here
I want to run a similar statement, but only opening certain files based on their corresponding flags. I thought about implementing it as a conditional_open
function, something like:
write_log = True
write_out_a = False
write_out_b = True
with conditional_open('log.txt', 'w', cond=write_log) as logfile, open('out_a.txt', 'w', cond=write_out_a) as out_a, open('out_b.txt', 'w', cond=write_out_b) as out_b:
# do something with logfile, out_a and out_b
# all files are closed here
But I'm a little confused as to how properly create that function. Ideally, coditional_open
would either return an open file handle or None
(in which case the file is never created/touched/deleted):
def conditional_open(filename, mode, cond):
return open(filename, mode) if cond else None
But I fear that this skips the benefits of the context manager when opening a file, since I'm calling open
outside from it. Is this assumption correct?
Can anyone give some ideas about how I could be doing this? I know I could create mock file objects based on the conditions and write to them instead, but it sounds a bit too convoluted to me - this seems like a simple problem, which should have a simple solution in Python.
Just set up your function as a context manager.
from contextlib import contextmanager
@contextmanager
def conditional_open(f_name, mode, cond):
if not cond:
yield None
resource = open(f_name, mode)
try:
yield resource
finally:
resource.close()