为什么重写 __iter__ 会抛出 RecursionError?
Why does overriding __iter__ throws RecursionError?
我想覆盖在外部库中定义的 ExternalIter
的 __iter__
方法,因此我无法更改 ExternalIter
class 的源代码。我在 MyIter2
和 MyIter3
.
中实现了两种不同的覆盖方式
class ExternalIter:
def __init__(self):
self.x = iter([
(1, 2),
(3, 4),
(5, 6),
(7, 8),
(9, 10)
])
def __iter__(self):
return self
def __next__(self):
return next(self.x)
class MyIter2(ExternalIter):
def __iter__(self):
while True:
try:
i, j = super().__next__()
yield i
yield j
except StopIteration:
break
class MyIter3(ExternalIter):
def __iter__(self):
for i, j in super().__iter__():
yield i
yield j
ExternalIter
的原始行为如下:
for i in ExternalIter():
print(i)
# (1, 2)
# (3, 4)
# (5, 6)
# (7, 8)
# (9, 10)
我想覆盖 __iter__
的行为,如下例所示:
for i in MyIter2():
print(i)
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
MyIter2
正常工作。然而,另一种替代方法就像我在 MyIter3
中所做的那样抛出 RecursionError
.
for i in MyIter3():
print(i)
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-8-4e1114201cac> in <module>
----> 1 for i in MyIter3():
2 print(i)
<ipython-input-5-82da3324a8a3> in __iter__(self)
30
31 def __iter__(self):
---> 32 for i, j in super().__iter__():
33 yield i
34 yield j
... last 1 frames repeated, from the frame below ...
<ipython-input-5-82da3324a8a3> in __iter__(self)
30
31 def __iter__(self):
---> 32 for i, j in super().__iter__():
33 yield i
34 yield j
RecursionError: maximum recursion depth exceeded while calling a Python object
您能解释一下为什么第二种覆盖方法会抛出错误而第一种方法有效吗?如何在不获取 RecursionError
的情况下使用 super().__iter__()
覆盖 __iter__
?
您能否解释一下 __iter__
在这种继承上下文中的工作原理,以了解为什么 super().__iter__()
指的是 self
而不是父项?
super().__iter__()
returns self
在 之前 for
循环会隐式调用 iter(self)
,这将启动无限递归。
由于 for
循环的工作原理,我在这里看不到任何使用方法。您可以使用显式 while
循环来避免调用 __iter__
.
def __iter__(self):
while True:
try:
i, j = next(self)
except StopIteration:
break
yield i
yield j
这不会将 self
视为可迭代对象,仅将其视为迭代器。
我想覆盖在外部库中定义的 ExternalIter
的 __iter__
方法,因此我无法更改 ExternalIter
class 的源代码。我在 MyIter2
和 MyIter3
.
class ExternalIter:
def __init__(self):
self.x = iter([
(1, 2),
(3, 4),
(5, 6),
(7, 8),
(9, 10)
])
def __iter__(self):
return self
def __next__(self):
return next(self.x)
class MyIter2(ExternalIter):
def __iter__(self):
while True:
try:
i, j = super().__next__()
yield i
yield j
except StopIteration:
break
class MyIter3(ExternalIter):
def __iter__(self):
for i, j in super().__iter__():
yield i
yield j
ExternalIter
的原始行为如下:
for i in ExternalIter():
print(i)
# (1, 2)
# (3, 4)
# (5, 6)
# (7, 8)
# (9, 10)
我想覆盖 __iter__
的行为,如下例所示:
for i in MyIter2():
print(i)
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
MyIter2
正常工作。然而,另一种替代方法就像我在 MyIter3
中所做的那样抛出 RecursionError
.
for i in MyIter3():
print(i)
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-8-4e1114201cac> in <module>
----> 1 for i in MyIter3():
2 print(i)
<ipython-input-5-82da3324a8a3> in __iter__(self)
30
31 def __iter__(self):
---> 32 for i, j in super().__iter__():
33 yield i
34 yield j
... last 1 frames repeated, from the frame below ...
<ipython-input-5-82da3324a8a3> in __iter__(self)
30
31 def __iter__(self):
---> 32 for i, j in super().__iter__():
33 yield i
34 yield j
RecursionError: maximum recursion depth exceeded while calling a Python object
您能解释一下为什么第二种覆盖方法会抛出错误而第一种方法有效吗?如何在不获取 RecursionError
的情况下使用 super().__iter__()
覆盖 __iter__
?
您能否解释一下 __iter__
在这种继承上下文中的工作原理,以了解为什么 super().__iter__()
指的是 self
而不是父项?
super().__iter__()
returns self
在 之前 for
循环会隐式调用 iter(self)
,这将启动无限递归。
由于 for
循环的工作原理,我在这里看不到任何使用方法。您可以使用显式 while
循环来避免调用 __iter__
.
def __iter__(self):
while True:
try:
i, j = next(self)
except StopIteration:
break
yield i
yield j
这不会将 self
视为可迭代对象,仅将其视为迭代器。