我正在尝试将CSV文件分类到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 数据?
您可以直接从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
无法打开它,但是由于您正在管道传输数据,因此不需要它。
这是设计使然。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
在文件之前读取 stdinmyarg1
或者如果您想在文件之后读取 stdin:... python3 my_script.py myarg1 -
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():
...