Python:循环逐个字符读取文本文件

3
例如,有一个文本文件,其中包含从0到9的数字:
0123456789
使用以下函数,我想要得到如下输出:
>>> print_char('filename')
0
>>> print_char('filename')
1
>>> print_char('filename')
2
.
.
.
>>> print_char('filename')
9

这意味着,每次调用该函数时,它都会返回下一个数字。
以下是我的函数:
def print_char(filename):
    f = open(filename, 'r')
    while True:
        char=f.read(1)
        if not char: 
            break
        print(char)

...以及我得到的输出:

>>> print_char('filename')
0
1
2
3
.
.
.
9

所以,如何创建一个函数,在每次调用时返回逐个字符?

你需要在 print_char 函数的调用之间共享状态(已读取的字符数量或仅打开的文件)。虽然可以使用全局变量实现此目的,但这种方法被认为是糟糕的设计。你真的需要带有这种行为的自由函数 print_char 吗? - rutsky
你提出的API不太好。使用x = Reader('filename'); x.next(); x.next() ...会更好。 - Jonathon Reinhart
1
@JonathonReinhart next(x) - Antti Haapala -- Слава Україні
1
我意识到我错误地假设你的文件是以换行符分隔的,因此我的解决方案对你没有帮助,因为你没有一个以换行符分隔的文件。Antti发布的新解决方案应该能够给你想要的结果。 - idjaw
1个回答

7

我会采用不同的方法,创建一个接受文件名并返回生成器的函数:

def reader(filename):
    with open(filename) as f:
        while True:
            # read next character
            char = f.read(1)
            # if not EOF, then at least 1 character was read, and 
            # this is not empty
            if char:
                yield char
            else:
                return

然后您只需要一次提供文件名。
r = reader('filename')

文件一直保持打开状态,以实现更快的操作。要获取下一个字符,请使用next内置函数。

print(next(r))  # 0
print(next(r))  # 1
...

您还可以使用itertools,例如在此对象上使用islice来切片字符,或者在for循环中使用它:

# skip characters until newline
for c in r:
    if r == '\n':
        break

1
这里假设文件中没有NUL字节,如果有的话会提前终止。我会将if char测试(在NUL上失败)更改为更明确的if len(char) == 1 - Jonathon Reinhart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接