【问题标题】:Strange nested loop behavior while handling an exception处理异常时奇怪的嵌套循环行为
【发布时间】:2016-09-02 21:41:36
【问题描述】:

目标:如果计数大于实际行数,在except 块中:告诉用户并让他们按回车。将count 设置为文件中的总行数并重试循环。

count = 10000
with open('mobydick_ch1.txt') as f:

        while 1:
            lines = []
            try:
                for i in range(count):
                    lines.append(next(f))  # iterate through file and append each line in range
                    break
            except StopIteration:
                if not input("File does not contain that many lines, press enter to continue printing maximum lines:"):
                    for i, k in enumerate(f, 1):
                        count = i

        f.close()  # close file

        # format output. enumerate lines, start at 1
        # http://stackoverflow.com/questions/4440516/in-python-is-there-an-elegant-
        # way-to-print-a-list-in-a-custom-format-without-ex
    print(''.join('Line {0}: {1}'.format(*k) for k in enumerate(lines, 1)))

我目前得到:

文件不包含那么多行,按回车继续打印最大行数:

每次我按回车键。是什么导致了这种不良行为?

【问题讨论】:

  • f.close() 完全是多余的;您已经将该文件用作上下文管理器 (with ...)
  • for i, k in enumerate(f, 1): count = i 循环的目标是什么?如果小于 10000,您是否尝试将 count 设置为文件中的实际行数?
  • 我不确定我是否理解您使用无限循环的原因。目标是等待文件获得更多行吗?你不能不重新打开。

标签: python file


【解决方案1】:

您已经用尽了文件,如果不返回 0,就无法再次读取文件再次。因此,您的 for i, k in enumerate(f, 1): 循环立即退出。这同样适用于while 1: 循环的每一次未来迭代;该文件仍在末尾,所有使用next() 的访问都将立即引发StopIteration

你已经知道你读了多少行,只需设置count = len(lines)。无需再次读取整个文件,只需设置count

如果你使用itertools.islice() 得到你的 1000 行会更好:

from itertools import islice

count = 10000
with open('mobydick_ch1.txt') as f:
    lines = list(islice(f, count))  # list of up to count lines
if len(lines) < count:
    input("File does not contain that many lines, press enter to continue printing maximum lines:")
    count = len(lines)  # set count to actual number of lines

如果您尝试等待直到文件至少包含count 行,您必须每次重新打开文件并寻找最后记录的位置:

lines = []
pos = 0
while len(lines) < count:
    with open('mobydick_ch1.txt') as f:
        f.seek(pos)
        lines.extend(islice(f, count - len(lines)))
        pos = f.tell()
    if len(lines) < count:
        input("File does not contain that many lines, press enter to continue printing maximum lines:")

【讨论】:

  • 感谢您的回复。如果列表为空,直到通过异常,我不确定在lines 中显示行是什么意思。我尝试将f.seek(0) 放在for i, k in enumerate(f, 1): 的正上方并得到相同的结果
  • @A.Michael: StopIteration 仅在没有更多行时引发。 到该点的所有行都添加到lines 列表中。如果lines 为空,则意味着文件中根本没有行,即文件开始时为空
  • @A.Michael:啊,你没有重新打开文件就无限循环......
  • @Marijn 感谢您的帮助和时间。我绝对可以使用你给我的东西。一路上学到了很多关于文件的知识!
猜你喜欢
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2010-10-12
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多