如果没有提供文件名,则回退到stdout

时间:2012-03-23 08:59:13

标签: python file stdout

我有一个脚本,它接受一个文件名而不是打开它并编写一些东西。

我使用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)

5 个答案:

答案 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 ......