2012-03-05 3 views
12

У меня есть класс в python, который имеет итерабельную переменную экземпляра. Я хочу повторить экземпляры класса, итерации по встроенному итерабельному.python make class iterable, возвращая встроенный iterable

Я реализовал это следующим образом:

def __iter__(self): 
    return self._iterable.__iter__() 

Я не чувствую, что удобно вызова метода __iter__() на итерацию, так как это специальный метод. Это как вы решили эту проблему в python или есть более элегантное решение?

+1

Возможно, вы захотите следить за PEP 380 (http://www.python.org/dev/peps/pep-0380/), что сделает это возможным с '' yield from self._iterable'' (это принимается к включению в 3.3). –

ответ

22

«Лучший» способ, как делегировать __iter__ бы:

def __iter__(self): 
    return iter(self._iterable) 

Попеременно, это может быть стоит знать:

def __iter__(self): 
    for item in self._iterable: 
     yield item 

Который позволит вам возиться с каждым элементом перед возвращением он (например, если вы хотите yield item * 2).

И как @Lattyware упоминает в комментариях, PEP380 (планируется для включения в Python 3.3) позволит:

def __iter__(self): 
    yield from self._iterable 

Обратите внимание, что это может быть заманчивым, чтобы сделать что-то вроде:

def __init__(self, iterable): 
    self.__iter__ = iterable.__iter__ 

Но это не будет работать: iter(foo) вызывает метод __iter__ на type(foo) напрямую, обходя foo.__iter__. Рассмотрим, например:

class SurprisingIter(object): 
    def __init__(self): 
     self.__iter__ = lambda self: iter("abc") 

    def __iter__(self): 
     return iter([1, 2, 3]) 

Вы ожидали бы, что list(SurprisingIter()) вернется ["a", "b", "c"], но на самом деле возвращает [1, 2, 3].

+0

да спасибо - это выглядит лучше! – jzwiener

+0

Очень хороший всеобъемлющий обзор! – kindall

+0

В варианте PEP380 есть опечатка, которую я предпочитаю. Это должно быть 'def __iter __ (self): yield from self._iterable' – kap

Смежные вопросы