2014-07-24 73 views
1

我有可定製的腳本,根據請求可以放棄3個不同的輸出文件。目前,我有:有條件地寫入不同的輸出文件

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

我運行到的是,如果不選擇該選項,仍然被創建的文件(因爲公開聲明的),它是想我避免這個問題。

天真什麼,我想我要的是沿着將被允許下面的線允許的語法:

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
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是複合語句,所以在正常的執行流程(無例外)這兩個大致equivivalent:

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

我試圖用這個做一些測試,但是它似乎只能寫入單個文件?另外,type1,type2和type3是不同的變量,默認爲False,在命令行中設置爲True,而不是設置爲指定值的單個變量。將更新問題以反映此更新的 – ded

+0

@ded以允許寫入多個文件。爲了使用'type1','type2','type3'作爲不同的變量,只需要替換'if user_wants_typeN(type):...'with'if typeN:...' – J0HN

+0

這很好,仍然有點侷限每個句柄都是單獨打開的,所以我必須爲每個3個句柄完成相同的「事情」。我會就此提出任何建議,但我會傾向於重新修改「某些東西」,以便將它分爲三種不同的類型。 – ded

0

它可以一次超過一種嗎?如果沒有,我會成立了寫這樣的文件條件之前:

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

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

這3種類型並不相互排斥。有人可能想要所有3種類型的任何組合,通常選項2和3一起選擇,但不一定是。 – ded

0

我只想找出該文件,你做任何開幕前所有。

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

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

這3種類型並不相互排斥。換句話說,有人可能想要所有3種類型的任何組合。 – ded

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