【问题标题】:Optional stdin in Python with argparse带有 argparse 的 Python 中的可选标准输入
【发布时间】:2011-11-26 10:51:25
【问题描述】:

我发现了非常有用的语法

parser.add_argument('-i', '--input-file', type=argparse.FileType('r'), default='-')

用于指定输入文件或使用标准输入——这两者都是我想要在我的程序中使用的。但是,并不总是需要输入文件。如果我不使用-i 或使用以下之一重定向输入

$ someprog | my_python_prog
$ my_python_prog < inputfile

我不希望我的 Python 程序等待输入。我希望它继续前进并使用默认值。

【问题讨论】:

    标签: python stdin argparse


    【解决方案1】:

    使用isattydetect,无论您的程序是处于交互式会话还是从文件中读取:

    if not sys.stdin.isatty(): # Not an interactive device.
      # ... read from stdin
    

    但是,为了一致性和可重复性,如果文件名是-,请考虑遵循规范并从标准输入读取。您可能需要考虑让fileinput 模块处理。

    【讨论】:

    • 这正是我想要的。谢谢!
    【解决方案2】:

    标准库documentation for 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'>)
    

    【讨论】:

    • 我知道我在前面的答案中说过这个,但 this 正是我想要的正是。谢谢。
    • 我非常困惑。 OP说输入文件并不总是需要的。那么为什么首先指定infile?为什么这些都是定位的?最后,为什么 OP 的代码不能工作? argparse 教程似乎暗示它应该可以正常工作......
    • @2rs2ts 为什么首先指定infile — 参数的特定顺序只是一个约定,您通常希望第一个参数指定输入,第二个指定输出。 为什么这些都是位置性的?——因为作者的偏好。位置参数的这种用法没有错。当您想从标准输入读取并写入文件(即app.py - outfile)时,在场景中使用可能会有点尴尬,但除了那个位置参数之外,它也可以正常工作。 为什么 OP 的代码不能工作? — 它实际上工作得很好 :)
    • @Mr.Deathless app.py - outfile 完美解释,谢谢。
    【解决方案3】:

    the answer regarding 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))
    

    【讨论】:

    • 好主意。这是最好的答案。
    猜你喜欢
    • 2013-11-26
    • 2016-01-14
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 2013-07-06
    • 2020-05-04
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多