2016-12-26 76 views
1

我正在尝试计算文件中的行数,但出现了奇怪的结果。下面有一个MWE,我相信这是不言而喻的:使用Python擦除文件中的行数擦除文件

file=open('Example.txt','r') 

print(sum(1 for line in file)) 
print(len(file.readlines())) 

当我运行它,我得到的输出X(行权数)和0。所以第二种方法要么不工作,要么读取一个空的变量。如果我切换顺序,我得到相同的结果,所以它正在工作,但不知何故变量被擦除。如果我使用相同的文件分配file_1file_2,并使用不同的变量运行每个方法,则会得到X和X,因此在完成操​​作后变量会被擦除。

我也试过从"r"改为"r+",但没有运气。有人可以解释这里发生了什么?对列表的操作不应该改变列表,至少这是我所教的内容。

谢谢!

回答

3

会发生什么事是:

print(sum(1 for line in file)) 

读取该文件,并排出,提供线迭代器。

当你然后做:

print(len(file.readlines())) 

你会0因为迭代器从以前的迭代用尽结束。使用file.seek(0)可以再次遍历它。

另外一个注意事项,当你读文件时不需要使用'r',它已经是默认模式了。


在一般情况下,你可以找出一个迭代获得通过它通过检查iter(obj) is obj一次迭代后耗尽:

f = open('example.txt') 
print(iter(f) is f) # True 

如果是这样的话,obj.__iter__回报self在其执行导致行为目击。

如果没有,例如采取列表:

l = [1, 2] 
print(iter(l) is l) # False 

__iter__方法返回一个有光泽的新的迭代器对象(列表,这是一个list_iterator对象),可以通过多次迭代。

+0

谢谢你,我不知道这样的事情可能发生。这个迭代器在哪里显式声明?我怎么知道我什么时候会遇到这个问题?根据我对C和MATLAB的经验,我必须重置迭代器,但在Python中,我确实认为这是一个内部过程。 'r'是我原来的代码中的剩余部分,我将使用'r +',但感谢您的提示! – Alegom

+0

它是一个内置的,因此它在'C'中实现(很确定位于['fileobject.c'](https://github.com/python/cpython/blob/master/Objects/fileobject.c)) 。你可以通过检查'iter(obj)是obj'来发现迭代器在迭代完成后会耗尽。如果是这种情况,'obj .__ iter__'在其实现中返回'self',导致所见证的行为。如果没有,'__iter__'方法返回一个闪亮的新迭代器对象,可以迭代多次@Alegom –

+0

你有什么建议我应该留意这个事件吗?在这种情况下,我的文件有15行。谁知道迭代器会很快耗尽? – Alegom