使用系统argv从stdin读取

时间:2018-06-27 11:00:04

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

我正在尝试将CS​​V文件添加到stdout,然后将打印的输出作为输入传递到python程序中,该程序也采用带有1个参数的系统参数向量。我遇到了一个问题,我认为这直接与Python的fileinput.input()函数在占用stdin文件描述符方面的反应有关。

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来运行此示例程序,则该程序能够评估并解析stdin以获取CSV文件输出的数据。

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

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

有人能够详细解释为什么此行为在Python中发生以及如何处理逻辑,以便Python程序可以在argv覆盖stdin描述符之前首先处理stdin数据吗?

3 个答案:

答案 0 :(得分:0)

您可以直接从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无法打开它,但是由于正在传输数据,因此不需要它。

答案 1 :(得分:0)

这是设计fileinput的概念制定者认为,在某些情况下,从stdin读取是没有意义的,只是提供了一种将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文件之前读取stdin,或者在... python3 my_script.py myarg1 -之后读取它,如果您想读取它,则

答案 2 :(得分:0)

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():
    ...