используя python 'with' с итераторами? - PullRequest
3 голосов
/ 12 марта 2010

Я использую Python 2.5. Я пытаюсь использовать это выражение «с».

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 для итераторов, но я хотел реализовать цикл while внутри генератора, который вызывается циклом for ... что-то как

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 ]

3 голосов
/ 12 марта 2010

Повышение StopIteration - это то, что делает итератор, когда добирается до конца. Обычно оператор for перехватывает его молча и переходит к предложению else, но если он повторяется вручную, как в вашем случае, то код должен быть подготовлен для обработки самого исключения.

1 голос
/ 12 марта 2010

Вы всегда можете переписать циклы while-with -licit-next. Когда у вас есть явный 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
1 голос
/ 12 марта 2010

У вас нет завершающих условий ни в одном из циклов while, поэтому вы продолжаете возвращаться, пока не получите исключение StopIteration, которое вы не обработали.

1 голос
/ 12 марта 2010

Ваш цикл while не заканчивается, но файл делает так, что он вызывает исключение StopIteration, когда нечего итерировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...