如何在 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)
我正在尝试复制 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)