Switch to argparse
(it's also part of the standard library) and use an
argparse.FileType
with a default value of stdin:
import argparse, sys
p = argparse.ArgumentParser()
p.add_argument('input', nargs='?',
type=argparse.FileType(), default=sys.stdin)
args = p.parse_args()
print(args.input.readlines())
This will not let you specify encoding and other parameters for stdin,
however; if you want to do that you need to make the argument non-optional
and let FileType
do its thing with stdin when -
is given as an
argument:
p.add_argument('input', type=FileType(encoding='UTF-8'))
Take heed that this latter case will not honour binary mode ('b'
) I/O. If
you need only that, you can use the default argument technique above, but
extract the binary I/O object, e.g., default=sys.stdout.buffer
for
stdout. However, this will still break if the user specifies -
anyway.
(With -
stdin/stdout is always wrapped in a TextIOWrapper
.)
If you want it to work with -
, or have any other arguments you need to
provide when opening the file, you can fix the argument if it got wrapped
wrong:
p.add_argument('output', type=argparse.FileType('wb'))
args = p.parse_args()
if hasattr(args.output, 'buffer'):
# If the argument was '-', FileType('wb') ignores the 'b' when
# wrapping stdout. Fix that by grabbing the underlying binary writer.
args.output = args.output.buffer
(Hat tip to medhat for
mentioning add_argument()
's type
parameter.)