Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fallback to stdout if no file name provided

I have a script that accepts as an argument a filename than opens it and writes some stuff.

I use the with statement:

with open(file_name, 'w') as out_file:
    ...
    out_file.write(...)

Now what if I want to write to sys.stdout if no file_name is provided?

Do I necessarily need to wrap all actions in a function and put a condition before?

if file_name is None:
    do_everything(sys.stdout)
else:
    with open(file_name, 'w') as out_file:
        do_everything(out_file)
like image 653
neurino Avatar asked Mar 23 '12 08:03

neurino


2 Answers

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

Then you can do

with file_or_stdout(file_name) as wfile:
    do_stuff_writing_to(wfile)
like image 152
glglgl Avatar answered Sep 25 '22 05:09

glglgl


How do you handle command line arguments? If you use argparse you could use the type and default parameters of add_argument to handle this. For example, try something like the following:

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:]))

If a file name is present as an argument the the script argparse will automatically open and close this file and args.infile will be a handle to this file. Otherwise args.infile will simply be sys.stdin.

like image 31
Chris Avatar answered Sep 22 '22 05:09

Chris