fileinput — 迭代来自多个输入流的行

源代码: Lib/fileinput.py


此模块实现了一个辅助类和函数,用于快速编写循环遍历标准输入或文件列表。如果您只想读取或写入一个文件,请参阅 open()

典型用法是

import fileinput
for line in fileinput.input(encoding="utf-8"):
    process(line)

这将迭代 sys.argv[1:] 中列出的所有文件的行,如果列表为空,则默认为 sys.stdin。如果文件名是 '-',它也会被替换为 sys.stdin,并且可选参数 *mode* 和 *openhook* 将被忽略。要指定文件名列表的替代项,请将其作为第一个参数传递给 input()。也允许使用单个文件名。

默认情况下,所有文件都以文本模式打开,但您可以通过在调用 input()FileInput 时指定 *mode* 参数来覆盖此行为。如果在打开或读取文件期间发生 I/O 错误,则会引发 OSError

在 3.3 版更改: 过去会引发 IOError;它现在是 OSError 的别名。

如果 sys.stdin 被使用多次,则第二次及以后的使用将不会返回任何行,除非是在交互式使用中,或者它已被显式重置(例如使用 sys.stdin.seek(0))。

空文件会被打开并立即关闭;只有当打开的最后一个文件为空时,它们在文件名列表中的存在才会被注意到。

返回的行将保留任何换行符,这意味着文件中的最后一行可能没有换行符。

您可以通过 *openhook* 参数向 fileinput.input()FileInput() 提供打开钩子来控制文件的打开方式。该钩子必须是一个函数,它接受两个参数,*filename* 和 *mode*,并返回一个相应打开的类文件对象。如果指定了 *encoding* 和/或 *errors*,它们将作为额外的关键字参数传递给钩子。此模块提供了一个 hook_compressed() 来支持压缩文件。

以下函数是此模块的主要接口

fileinput.input(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

创建 FileInput 类的实例。该实例将用作此模块函数的全局状态,并在迭代期间返回以供使用。此函数的参数将传递给 FileInput 类的构造函数。

FileInput 实例可以在 with 语句中用作上下文管理器。在此示例中,即使发生异常,*input* 也会在退出 with 语句后关闭

with fileinput.input(files=('spam.txt', 'eggs.txt'), encoding="utf-8") as f:
    for line in f:
        process(line)

在 3.2 版更改: 可以用作上下文管理器。

在 3.8 版更改: 关键字参数 *mode* 和 *openhook* 现在仅为关键字参数。

在 3.10 版更改: 添加了仅限关键字的参数 *encoding* 和 *errors*。

以下函数使用 fileinput.input() 创建的全局状态;如果没有活动状态,则会引发 RuntimeError

fileinput.filename()

返回当前正在读取的文件的名称。在读取第一行之前,返回 None

fileinput.fileno()

返回当前文件的整数“文件描述符”。当没有打开文件时(在第一行之前和文件之间),返回 -1

fileinput.lineno()

返回刚刚读取的行的累积行号。在读取第一行之前,返回 0。在读取最后一个文件的最后一行之后,返回该行的行号。

fileinput.filelineno()

返回当前文件中的行号。在读取第一行之前,返回 0。在读取最后一个文件的最后一行之后,返回该行在文件中的行号。

fileinput.isfirstline()

如果刚读取的行是其文件的首行,则返回 True,否则返回 False

fileinput.isstdin()

如果最后一行是从 sys.stdin 读取的,则返回 True,否则返回 False

fileinput.nextfile()

关闭当前文件,以便下一次迭代将从下一个文件(如果有)读取第一行;未从文件中读取的行将不计入累积行数。在读取下一个文件的第一行之前,文件名不会更改。在读取第一行之前,此函数无效;它不能用于跳过第一个文件。在读取最后一个文件的最后一行之后,此函数无效。

fileinput.close()

关闭序列。

实现模块提供的序列行为的类也可用于子类化

class fileinput.FileInput(files=None, inplace=False, backup='', *, mode='r', openhook=None, encoding=None, errors=None)

FileInput 是实现;它的方法 filename()fileno()lineno()filelineno()isfirstline()isstdin()nextfile()close() 对应于模块中同名的函数。此外,它是 可迭代的,并且有一个 readline() 方法,该方法返回下一个输入行。必须按严格的顺序访问序列;随机访问和 readline() 不能混合使用。

使用 mode,您可以指定将传递给 open() 的文件模式。它必须是 'r''rb' 之一。

openhook(如果给出)必须是一个函数,它接受两个参数,filenamemode,并返回一个相应打开的类文件对象。您不能同时使用 inplaceopenhook

您可以指定传递给 open()openhookencodingerrors

FileInput 实例可以在 with 语句中用作上下文管理器。在此示例中,即使发生异常,input 也会在退出 with 语句后关闭

with FileInput(files=('spam.txt', 'eggs.txt')) as input:
    process(input)

在 3.2 版更改: 可以用作上下文管理器。

版本 3.8 中的变化: 关键字参数 modeopenhook 现在仅限关键字。

在 3.10 版更改: 添加了仅限关键字的参数 *encoding* 和 *errors*。

版本 3.11 中的变化: 'rU''U' 模式以及 __getitem__() 方法已被删除。

**可选的原地过滤:** 如果关键字参数 inplace=True 传递给 fileinput.input()FileInput 构造函数,则文件将移动到备份文件,并将标准输出定向到输入文件(如果已存在与备份文件同名的文件,它将被静默替换)。这使得编写一个过滤器来原地重写其输入文件成为可能。如果给出了 backup 参数(通常为 backup='.<some extension>'),它指定备份文件的扩展名,并且备份文件会保留;默认情况下,扩展名为 '.bak',并且在输出文件关闭时删除。读取标准输入时,原地过滤被禁用。

此模块提供了以下两个打开钩子

fileinput.hook_compressed(filename, mode, *, encoding=None, errors=None)

使用 gzipbz2 模块透明地打开使用 gzip 和 bzip2 压缩的文件(通过扩展名 '.gz''.bz2' 识别)。如果文件名扩展名不是 '.gz''.bz2',则文件将正常打开(即,使用 open() 而不进行任何解压缩)。

encodingerrors 值将传递给压缩文件的 io.TextIOWrapper 和普通文件的 open。

使用示例: fi = fileinput.FileInput(openhook=fileinput.hook_compressed, encoding="utf-8")

在 3.10 版更改: 添加了仅限关键字的参数 *encoding* 和 *errors*。

fileinput.hook_encoded(encoding, errors=None)

返回一个钩子,它使用给定的 encodingerrors 来读取文件,并使用 open() 打开每个文件。

使用示例: fi = fileinput.FileInput(openhook=fileinput.hook_encoded("utf-8", "surrogateescape"))

在 3.6 版更改: 添加了可选的 errors 参数。

3.10 版后已弃用: 此函数已弃用,因为 fileinput.input()FileInput 现在具有 encodingerrors 参数。