如何在 class 上正确实现 python __iter__?

How to correctly implement python __iter__ on a class?

我正在尝试复制 python 列表迭代,但与 python 列表不同,我的循环索引不会在嵌套循环内重新启动。

目前第一种情况按预期工作,但第二种情况永远循环,因为内部和外部循环都共享相同的 myClassObj,并且内部循环总是将索引重置为起始值,因此外部循环永远不会终止。如何让它表现得像 python 内置列表?

class MyClass:
    """Iterator for looping over a sequence."""
    def __init__(self, seq):
        self.data = seq
        self.index = -1

    def __iter__(self):
        return self

    def __next__(self):
        """Return the next element, or else raise StopIteration error."""
        self.index += 1
        if self.index < len(self.data):
            return self.data[self.index]
        else:
            self.index = -1
            raise StopIteration()


myClassObj = MyClass('spa')

# Case1: This Works fine:
for i in range(2):
    for each in myClassObj:
        print(each)
    print()
print()

# Case2: This does not work correctly.
for each in myClassObj:
    for each1 in myClassObj:
        print('{}: {}'.format(each, each1))
    print()

第二种情况的预期行为是:

s: s
s: p
s: a

p: s
p: p
p: a

a: s
a: p
a: a

你说得对,你的代码无法正常工作,因为 self.index 由 each 和 each1 共享(因为它们都使用同一个 MyClass 实例 myClassObj) 试试这个:

class SeqIter:
    def __init__(self, seq):
        self._seq = seq
        self._i = 0

    def __next__(self):
        if self._i >= len(self._seq):
            raise StopIteration
        next_item = self._seq[self._i]
        self._i += 1
        return next_item


class Seq:
    def __init__(self, seq):
        self._seq = seq

    def __iter__(self):
        return SeqIter(self._seq)

运行测试代码:

seq = 'spa'
seq_obj = Seq(seq)
for i in seq_obj:
    for j in seq_obj:
        print(i, j)