Conditional write to different output files

advertisements

I have customizable script that can give up to 3 different output files depending on what is requested. Currently I have:

with open("option1", "w") as file1, open("option2", "w") as file2, open("option3", "w") as file3:

The issue I'm running into is if the option is not selected, the file is still being created (because of the open statement) which is what I'd like to avoid.

Naively what I think I want is an allowed syntax along the lines of the following that would be allowed:

with (if type1: open("option1", "w") as file1), (if type2: open("option2", "w") as file2), (if type3: open("option3", "w") as file3):

The 3 different types and corresponding options are not mutually exclusive, it is common to want more than 1 of the file types. The type1, type2, and type3 variables are booleans that are set to False by default and toggled independently to True at the command line. Overall I'm trying to efficiently avoid the creation of empty files, and am open to even fairly drastic changes in code to accomplish it.


filenames_map = {"type1":"option1", "type2":"option2", "type3":"option3"}
filename = filenames_map.get(type, "default_option")
with open(filname, "w") as targetFile:
    # do whatever needs to be done

dict.get gets value from the dictionary and defaults to second argument of no such key found.

If types are not mutually exclusive it's a little bit trickier. with is a compound statement, so under normal execution flow (no exceptions) these two are roughly equivivalent:

with (context_manager) as something:
    do_stuff()  

try:
    context_manager.__enter__()
    do_stuff()
finally:
    context_manager.__exit__()

So, if you can't determine the number of files to write to until runtime, you'll have to manage context yourself. Luckily, open returns FileObject, hich are context managers with __enter__ and __exit__ defined. Luckily, open returns FileObject which is a quite simple context manager. As stated in documentation

with open("hello.txt") as f:
    for line in f:
        print line,

Is equal to

f = open("hello.txt")
try:
    for line in f:
        print line,
finally:
    f.close()

Now, to the point

target_files = []
# please modify to follow PEP-8 yourself, compressed for clarity
if user_wants_type1(type): target_files.append("option1")
if user_wants_type2(type): target_files.append("option2")
if user_wants_type3(type): target_files.append("option3")

try:
    handles = [open(filename) for filename in taget_files]
    for handle in handles:
        handle.write("something")
finally:
    for handle in handles:
        handle.close()