python循环输入文件

14 python file-io for-loop

我的问题与Python中的文件输入有关,使用open().我有一个mytext.txt包含3行的文本文件.我正在尝试使用此文件执行两项操作:打印行,并打印行数.

我尝试了以下代码:

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
for line in input_file:
    count_lines += 1
print 'number of lines:', count_lines
Run Code Online (Sandbox Code Playgroud)

结果:它正确打印3行,但打印"行数:0"(而不是3)


我找到了两种解决方法,并将其打印出来3:

1)我使用一个循环而不是两个循环

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
    count_lines += 1
print 'number of lines:', count_lines
Run Code Online (Sandbox Code Playgroud)

2)在第一个循环之后,我再次定义input_file

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
input_file = open('mytext.txt', 'r')
for line in input_file:
    count_lines += 1
print 'number of lines:', count_lines
Run Code Online (Sandbox Code Playgroud)

对我来说,似乎该定义input_file = ...仅对一个循环有效,就好像它在我用它循环后被删除一样.但我不明白为什么,可能它还没有100%清楚,我是如何variable = open(filename)用Python处理的.

顺便说一下,我看到在这种情况下最好只使用一个循环.但是,我觉得我必须清楚这个问题,因为有些情况我可以/必须使用它.

Pau*_*ine 23

文件句柄是一个迭代器.迭代文件后,指针将定位在EOF(文件末尾),迭代器将引发退出循环的StopIteration.如果你试图将一个迭代器用于指针位于EOF的文件,它只会引发StopIteration并退出:这就是为什么它在第二个循环中计数为零的原因.您可以在input_file.seek(0)不重新打开的情况下回放文件指针.

也就是说,在同一个循环中计数行的I/O效率更高,否则你必须再次从磁盘读取整个文件来计算行数.这是一种非常常见的模式:

with open('filename.ext') as input_file:
    for i, line in enumerate(input_file):
        print line,
print "{0} line(s) printed".format(i+1)
Run Code Online (Sandbox Code Playgroud)

在Python 2.5中,文件对象已经配备__enter____exit__处理with语句接口.这是类似于以下内容的语法糖:

input_file = open('filename.txt')
try:
    for i, line in enumerate(input_file):
        print line,
finally:
    input_file.close()
print "{0} line(s) printed".format(i+1)
Run Code Online (Sandbox Code Playgroud)

我认为cPython会在收集垃圾时关闭文件句柄,但我不确定这是否适用于每个实现 - 恕我直言,明确关闭资源句柄是更好的做法.


Wug*_*Wug 5

有什么理由你不能使用以下内容:

input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
    print line
    count_lines += 1
print 'number of lines:', count_lines
Run Code Online (Sandbox Code Playgroud)

open返回的东西是一个文件对象.当你循环遍历它们时,文件对象会跟踪它们自己的内部位置,所以为了做你先尝试过的事情,你必须手动将它倒回到开头,它不会自己完成它.