在EOF优雅地退出

时间:2016-07-08 08:32:35

标签: python eof

我正在尝试解析一个文件,其中有一个部分始终存在,而过去的部分是可选的。

for line in finp:
    # This part is always present
    for _ in range(int(ldata[2])):
        sdata = finp.readline()
        tdos.write(sdata)


    #This part may or may not be present
    for i in range(int(atoms)):
        next(finp)
        for j in range(int(ldata[2])):
            aatom[i][j] = [float(x) for x in
                           finp.readline().strip().split()]

问题是,如果不存在可选部分,next(finp)会出错:

    next(finp)
StopIteration

我尝试过:

for i in range(int(atoms)):
    if i is not None:
        next(finp)
        for j in range(int(ldata[2])):
            aatom[i][j] = [float(x) for x in
                           finp.readline().strip().split()]
    else:
        break

但这并没有解决问题。我发现许多以前的问题与this相同,但无法解决此问题。

解决它的唯一方法,如接受的ans中所述,是立即读取整个文件然后处理?

1 个答案:

答案 0 :(得分:4)

next()默认返回:

next(finp, None)

当给出第二个参数时,next()捕获一个StopIteration异常并返回第二个参数。

另一种方法是自己抓住StopIteration;也许你想在这一点上摆脱循环:

try:
    next(finp)
except StopIteration:
    break

请注意,您还混合了file.readline()next(file)。由于Python 2中的实现细节,您将遇到意外行为,因为这两个方法共享其缓存。坚持在这里使用next()(因为for循环也将file视为迭代器)。请参阅File Objects文档:

  

为了使for循环成为循环文件行的最有效方式(一种非常常见的操作),next()方法使用隐藏的预读缓冲区。使用预读缓冲区的结果是,将next()与其他文件方法(如readline())组合不起作用。但是,使用seek()将文件重新定位到绝对位置将刷新预读缓冲区。

如果你使用的是Python 3,你可以忽略这个警告,但你最好还是坚持使用这两种方法中的一种。