使用python'with'语句与迭代器?

时间:2010-03-12 04:24:48

标签: python

我正在使用Python 2.5。我正在尝试使用这个'with'语句。

from __future__ import with_statement
a = []
with open('exampletxt.txt','r') as f:
    while True:
        a.append(f.next().strip().split())
print a

'exampletxt.txt'的内容很简单:

a
b

在这种情况下,我收到错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/tmp/python-7036sVf.py", line 5, in <module>
    a.append(f.next().strip().split())
StopIteration

如果我用f.next()替换f.read(),它似乎陷入无限循环。

我想知道是否必须编写一个接受迭代器对象作为参数的装饰器类,并为它定义__exit__方法?

我知道为迭代器使用for循环更加pythonic,但我想在一个由for循环调用的生成器中实现while循环... like

def g(f):
    while True:
        x = f.next()
        if test1(x):
            a = x
        elif test2(x):
            b = f.next()
            yield [a,x,b]

a = []
with open(filename) as f:
    for x in g(f):
        a.append(x)

4 个答案:

答案 0 :(得分:4)

提升StopIteration是迭代器到达时的作用。通常,for语句会以静默方式捕获它,并继续执行else子句,但如果在您的情况下手动迭代,那么代码必须准备好处理异常本身。

答案 1 :(得分:1)

你的while循环没有结束,但文件是这样做的,当没有其他东西可以迭代时,它会引发一个StopIteration异常。

答案 2 :(得分:1)

您的任何while循环中都没有任何终止条件,因此您将一直返回,直到您获得无法处理的StopIteration异常。

答案 3 :(得分:1)

您始终可以使用显式下一个循环重写。当你有一个明确的next时,你只是向前看一个标记。

通常,可以重写此表单的循环。

def g(f):
    while True:
        x = f.next()
        if test1(x):
            a = x
        elif test2(x):
            b = f.next()
            yield [a,x,b]

您可以随时通过缓冲值替换前瞻next

def g(f):
    prev, a = None, None
    for x in f:
        if test2(prev)
            yield [ a, prev, x ]
        elif test1(x):
            a = x
        prev= x