Как этот класс реализует метод "__iter__" без реализации "next"? - PullRequest
20 голосов
/ 25 декабря 2009

У меня есть следующий код в django.template:

class Template(object):
    def __init__(self, template_string, origin=None, name='<Unknown Template>'):
        try:
            template_string = smart_unicode(template_string)
        except UnicodeDecodeError:
            raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.")
        if settings.TEMPLATE_DEBUG and origin is None:
            origin = StringOrigin(template_string)
        self.nodelist = compile_string(template_string, origin)
        self.name = name

    def __iter__(self):
        for node in self.nodelist:
            for subnode in node:
                yield subnode

    def render(self, context):
        "Display stage -- can be called many times"
        return self.nodelist.render(context)

Часть, в которой я запутался, ниже. Как работает этот __iter__ метод? Я не могу найти соответствующий next метод.

def __iter__(self):
        for node in self.nodelist:
            for subnode in node:
                yield subnode

Это единственный способ, который я знаю, как реализовать __iter__:

class a(object):
    def __init__(self,x=10):
        self.x = x
    def __iter__(self):
        return self
    def next(self):
        if self.x > 0:
            self.x-=1
            return self.x
        else:
            raise StopIteration
 ainst = a()
 for item in aisnt:
     print item

В своих ответах, пожалуйста, старайтесь использовать примеры кода, а не текст, потому что мой английский не очень хорош. Спасибо.

Ответы [ 2 ]

36 голосов
/ 25 декабря 2009

Из документов :

Если объект контейнера __iter__() метод реализован как генератор, он автоматически вернет объект итератора (технически, генератор объекта) поставка __iter__() и next() методы.

14 голосов
/ 25 декабря 2009

Этот метод __iter__ возвращает генератор Python (см. Документацию ), поскольку он использует ключевое слово yield. Генератор автоматически предоставит метод next (); цитирование документации:

Что делает генераторы такими компактными, так это то, что методы __iter __ () и next () созданы автоматически.

РЕДАКТИРОВАТЬ:

Генераторы действительно полезны. Если вы не знакомы с ними, я предлагаю вам ознакомиться с ними и поиграть с тестовым кодом.

Вот еще немного информации об итераторах и генераторах из StackOverflow .

...