我有一个脚本,它接受一个文件名而不是打开它并编写一些东西。
我使用with
声明:
with open(file_name, 'w') as out_file:
...
out_file.write(...)
如果我没有提供sys.stdout
,我现在想要写file_name
该怎么办?
我是否一定需要在函数中包装所有操作并在之前设置条件?
if file_name is None:
do_everything(sys.stdout)
else:
with open(file_name, 'w') as out_file:
do_everything(out_file)
答案 0 :(得分:6)
from contextlib import contextmanager
@contextmanager
def file_or_stdout(file_name):
if file_name is None:
yield sys.stdout
else:
with open(file_name, 'w') as out_file:
yield out_file
然后你可以做
with file_or_stdout(file_name) as wfile:
do_stuff_writing_to(wfile)
答案 1 :(得分:3)
如何处理命令行参数?如果您使用argparse
,则可以使用add_argument
的{{3}}和type
参数来处理此问题。例如,尝试以下内容:
import sys
import argparse
def main(argv=None):
if argv is None:
argv=sys.argv[1:]
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?',
type=argparse.FileType('w'),
default=sys.stdin)
args = parser.parse_args(argv)
print args.infile
return 0
if __name__=="__main__":
sys.exit(main(sys.argv[1:]))
如果文件名作为参数出现,脚本argparse将自动打开并关闭此文件,args.infile
将成为此文件的句柄。否则args.infile
将只是sys.stdin
。
答案 2 :(得分:2)
您可以编写自己的上下文管理器。如果没有其他人
,我会稍后发布示例代码答案 3 :(得分:0)
if file_name is None:
fd = sys.stdout
else:
fd = open(file_name, 'w')
# write to fd
if fd != sys.stdout:
fd.close();
答案 4 :(得分:0)
使用with ... as
构造对于自动关闭文件很有用。这意味着,如我所知,将其与sys.stdout
一起使用会崩溃您的程序,因为它会尝试关闭系统标准输出!
这意味着像with open(name, 'w') if name else sys.stdout as:
这样的东西不起作用。
这让我说没有任何简单好的方法可以更好地编写你的代码片段...但是可能有更好的方法来思考如何构建这样的代码!
要明确的要点是,当存在file_name时,需要打开(并且更重要的是,关闭)file_name
的文件处理程序。
我个人只是放弃with .. as
并打开文件 - 更重要的是,关闭它! - 别的地方。根据软件的工作方式,里程可能会有所不同。
这意味着你可以做到:
out_file = open(file_name, 'w') if file_name else sys.stdout
并在整个程序中使用out_file。
当你关闭时,记得检查它是否是文件:)
您是否想过简单地使用logging
模块?这很容易让你添加不同的处理程序,打印到文件,打印到stdout ......