有条件地写入不同的输出文件

时间:2014-07-24 16:25:55

标签: python if-statement with-statement

我有可自定义的脚本,可以根据请求提供最多3个不同的输出文件。目前我有:

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

我遇到的问题是如果未选择该选项,则仍在创建文件(因为open语句),这是我想要避免的。

天真的我认为我想要的是允许的语法,如下所示:

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

3种不同的类型和相应的选项并不相互排斥,通常需要1种以上的文件类型。 type1,type2和type3变量是布尔值,默认情况下设置为False,并在命令行中独立切换为True。总的来说,我试图有效地避免创建空文件,并且即使是相当剧烈的代码更改也可以实现它。

4 个答案:

答案 0 :(得分:4)

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从字典中获取值,默认为没有找到此键的第二个参数。

如果类型不相互排斥,那就有点棘手了。 with是一个复合语句,因此在正常执行流程(无例外)下,这两个大致相当:

with (context_manager) as something:
    do_stuff()  

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

因此,如果在运行时之前无法确定要写入的文件数,则必须自己管理上下文。幸运的是,open返回FileObject,其中定义了__enter____exit__的上下文管理员。幸运的是,open返回FileObject这是一个非常简单的上下文管理器。如documentation

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

等于

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

现在,到了

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

答案 1 :(得分:1)

如果您使用的是Python3,则可以使用contextlib.ExitStack:

import contextlib
filenames = ['option{}'.format(i) for i in range(1,4)]
types = [type1, type2, type3]

with contextlib.ExitStack() as stack:
    files = [stack.enter_context(open(filename, 'w'))
             for filename, typ in zip(filenames, types) if typ]

对于Python2,您可以使用contextlib2 module

答案 2 :(得分:0)

一次可以多种类型吗?如果没有,我会在写入文件之前设置一个条件:

if type1:
    fname = "option1"
elif type2:
    fname = "option2"
elif type3:
    fname = "option3"

with open(fname, "w") as outfile:
    outfile.write("ok!")

答案 3 :(得分:0)

我会在你完成任何开放之前弄清楚该文件。

if type1:
    filename = "option1"
elif type2:
    filename = "option2"
elif type3:
    filename = "option3"

with open(filename, 'w') as outfile:
    #do stuff