Python通过返回嵌入式可迭代对象使类变为可迭代对象。

12

我有一个Python类,其中有一个可迭代的实例变量。我想通过遍历嵌入的可迭代对象来迭代该类的实例。

我按照以下方式实现了这一点:

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中)。 - Gareth Latty
1个回答

23

委托 __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)会直接调用type(foo)上的__iter__方法,绕过了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]


PEP380的变体中有一个错别字,我更喜欢它。应该是 def __iter__(self): yield from self._iterable - kap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接