使用argparse在Python中使用可选的stdin

Jus*_*rce 60 python stdin argparse

我发现了非常有用的语法

parser.add_argument('-i', '--input-file', type=argparse.FileType('r'), default='-')
Run Code Online (Sandbox Code Playgroud)

用于指定输入文件或使用stdin - 我想在程序中使用它们.但是,并不总是需要输入文件.如果我没有使用-i或重定向输入

$ someprog | my_python_prog
$ my_python_prog < inputfile
Run Code Online (Sandbox Code Playgroud)

我不希望我的Python程序等待输入.我希望它只是移动并使用默认值.

mik*_*ers 106

argparse的标准库文档建议此解决方案允许可选的输入/输出文件:

>>> 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'>)
Run Code Online (Sandbox Code Playgroud)

  • 我知道我之前的回答是这么说的,但是_this_是_exactly_我​​正在寻找的东西.谢谢. (4认同)
  • 我绝对不知所措.OP表示并不总是需要输入文件.那么为什么首先指定`infile`?为什么这些位置呢?最后,为什么OP的代码不起作用呢?`argparse`教程似乎意味着它应该工作得很好...... (4认同)

phi*_*hag 22

使用isatty检测您的程序是在交互式会话中还是从文件中读取:

if not sys.stdin.isatty(): # Not an interactive device.
  # ... read from stdin
Run Code Online (Sandbox Code Playgroud)

但是,为了保持一致性和可重复性,请考虑遵循规范并从文件名中读取文件名-.您可能需要考虑让fileinput模块处理它.


pal*_*wim 10

基于关于 TTY detection 的答案,明确回答这个问题:

import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input-file', type=argparse.FileType('r'), default=(None if sys.stdin.isatty() else sys.stdin))
Run Code Online (Sandbox Code Playgroud)