Optional stdin in Python with argparse
The standard library documentation for argparse suggests this solution to allow optional input/output files:
>>> parser = argparse.ArgumentParser()>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),... default=sys.stdin)>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),... default=sys.stdout)>>> parser.parse_args(['input.txt', 'output.txt'])Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)>>> parser.parse_args([])Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
Use isatty to detect whether your program is in an interactive session or reading from a file:
if not sys.stdin.isatty(): # Not an interactive device. # ... read from stdin
However, for the sake of consistency and reproducability, consider following the norm and reading from stdin if the filename is -
. You may want to consider to let the fileinput
module handle that.
Building on top of the answer regarding TTY detection, to answer the question explicitly:
import sysimport argparseparser = argparse.ArgumentParser()parser.add_argument('-i', '--input-file', type=argparse.FileType('r'), default=(None if sys.stdin.isatty() else sys.stdin))