16

我的问题与 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

结果:它正确打印了 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

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

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

顺便说一句,我发现在这种情况下最好只使用一个循环。但是,我觉得我必须弄清楚这个问题,因为在某些情况下我可以/必须使用它。

4

4 回答 4

26

文件句柄是一个迭代器。遍历文件后,指针将定位在 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)

在 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)

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

于 2012-07-30T17:21:31.793 回答
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

open 返回的东西是一个文件对象。文件对象在您遍历它们时会跟踪它们自己的内部位置,因此为了执行您首先尝试的操作,您必须手动将其倒回到开头,它不会自行完成。

于 2012-07-30T17:20:03.210 回答
2

尝试input_file.seek(0)在两个循环之间添加一个。这会将文件倒回到开头,因此您可以再次循环播放它。

于 2012-07-30T17:20:15.623 回答
0

我瘦了你想要的模块文件输入。

链接在这里

if __name__ == "__main__":
for line in fileinput.input():
    if fileinput.isfirstline():
        print("current file: %s" % fileinput.filename())

    print("line number: %d, current file number: %d" % 
          (fileinput.lineno(), fileinput.filelineno()))
于 2013-06-10T11:38:27.747 回答