【问题标题】:Reading from stdin with a system argv使用系统 argv 从标准输入读取
【发布时间】:2018-06-27 20:30:16
【问题描述】:

我正在尝试将 CSV 文件分类到标准输出中,然后将打印输出作为输入通过管道传输到 python 程序中,该程序还采用带有 1 个参数的系统参数向量。我遇到了一个我认为与 Python 的 fileinput.input() 函数在占用标准输入文件描述符方面的反应直接相关的问题。

generic_user% cat my_data.csv | python3 my_script.py myarg1

这是一个示例 Python 程序:

import sys, fileinput

def main(argv):
    print("The program doesn't even print this")
    data_list = []
    for line in fileinput.input():
        data_list.append(line)

if __name__ == "__main__":
    main(sys.argv)

如果我尝试使用上述终端命令且不带参数 myarg1 运行此示例程序,则该程序能够评估和解析标准输入以获取 CSV 文件的数据输出。

如果我使用参数 myarg1 运行程序,它最终会抛出与 myarg1 不作为文件存在直接相关的 FileNotFoundError。

FileNotFoundError: [Errno 2] No such file or directory: 'myarg1'

谁能详细解释一下为什么在 Python 中会发生这种行为以及如何处理逻辑,以便 Python 程序可以在 argv 覆盖标准输入描述符之前首先处理标准输入数据?

【问题讨论】:

  • 你在哪里使用 sys.argv?你试过generic_user% cat my_data.csv | python3 my_script.py吗?

标签: python python-3.x file-io file-descriptor


【解决方案1】:

您可以直接阅读stdin

import sys

def main(argv):
    print("The program doesn't even print this")
    data_list = []
    for line in iter(sys.stdin):
        data_list.append(line)

if __name__ == "__main__":
    main(sys.argv)

您正在尝试访问尚未创建的文件,因此 fileinput 无法打开它,但由于您正在管道传输数据,因此您不需要它。

【讨论】:

    【解决方案2】:

    这是设计的fileinput 的概念者认为在某些用例中从标准输入读取是没有意义的,并且只是提供了一种专门将 stdin 添加到文件列表的方法。根据参考文档:

    import fileinput
    for line in fileinput.input():
        process(line)
    

    这会遍历 sys.argv[1:] 中列出的所有文件的行,如果列表为空,则默认为 sys.stdin。 如果文件名是 '-',它也被 sys.stdin 替换

    只需保留您的代码并使用:generic_user% cat my_data.csv | python3 my_script.py - myarg1

    myarg1 文件之前读取标准输入,或者如果您想在之后读取它:... python3 my_script.py myarg1 -

    【讨论】:

      【解决方案3】:

      fileinput 实现了 Unix 实用程序常见的模式:

      • 如果使用命令行参数调用实用程序,则它们是要读取的文件。
      • 如果调用时不带参数,则从标准输入读取。

      所以fileinput 完全按照预期工作。目前尚不清楚您使用命令行参数的目的是什么,但如果您不想停止使用fileinput,则应在调用它之前修改sys.argv

      some_keyword = sys.argv[1]
      sys.argv = sys.argv[:1]      # Retain only argument 0, the command name
      
      for line in fileinput.input():
          ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-30
        • 2012-02-17
        • 2019-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多