我的问题与使用open()
的Python中的文件输入有关。我有一个包含3行的文本文件mytext.txt
。
我正在尝试使用此文件执行两项操作:打印行,并打印行数。
我尝试了以下代码:
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处理。
顺便说一句,我看到在这种情况下最好只使用一个循环。但是,我觉得我必须清楚这个问题,因为有些情况我可以/必须使用它。
答案 0 :(得分:22)
文件句柄是一个迭代器。迭代文件后,指针将定位在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
statement interface问题。这是语法糖,如:
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会在收集垃圾时关闭文件句柄,但我不确定这是否适用于每个实现 - 恕我直言,显式关闭资源句柄是更好的做法。
答案 1 :(得分: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返回的东西是一个文件对象。文件对象在循环时跟踪它们自己的内部位置,所以为了完成你先尝试过的操作,你必须手动将它倒回到开头,它不能单独完成。
答案 2 :(得分:2)
尝试在两个循环之间添加input_file.seek(0)
。这会将文件回退到开头,因此您可以再次循环它。
答案 3 :(得分: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()))