Python 作为迭代器成员函数的生成器
因此我理解,有时候,在一个类中定义iter和next方法,而不是应该是可iterable的,只使用包含yield语句的iter方法就足够了。为什么呢?只是要避免样板代码 然而,我不明白为什么下面的代码片段会产生三次迭代Python 作为迭代器成员函数的生成器,python,iterator,Python,Iterator,因此我理解,有时候,在一个类中定义iter和next方法,而不是应该是可iterable的,只使用包含yield语句的iter方法就足够了。为什么呢?只是要避免样板代码 然而,我不明白为什么下面的代码片段会产生三次迭代 class BoundedRepeater: def __init__(self, value, max_repeats): self.value = value self.max_repeats = max_repeats
class BoundedRepeater:
def __init__(self, value, max_repeats):
self.value = value
self.max_repeats = max_repeats
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count >= self.max_repeats:
raise StopIteration
self.count += 1
return self.value
如果这样叫
for item in BoundedRepeater("Hello", 3):
print(item)
但是如果我把方法改成
类BoundedRepeater:
definit(自身、值、最大重复次数):
自我价值=价值
self.max\u repeats=max\u repeats
self.count=0
class BoundedRepeater:
def __init__(self, value, max_repeats):
self.value = value
self.max_repeats = max_repeats
self.count = 0
def __iter__(self):
if self.count >= self.max_repeats:
raise StopIteration
self.count += 1
yield self.value
我只得到一次迭代而不是三次您可以使用生成器函数,但您应该在循环中生成结果,在您的情况下,以数字为界
max\u repeat
我认为你的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法应该写如下:
def __iter__(self):
for i in range(self.max_repeats):
yield self.value
return
我试过了,它生成了max_occurrences中指定的项目数
br = BoundedRepeater('tagada', 5)
for item in br:
print(item)
# ->tagada
# ->tagada
# ->tagada
# ->tagada
# ->tagada
您可以使用生成器函数,但应在循环中生成结果,以数字
max\u repeat
我认为你的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法应该写如下:
def __iter__(self):
for i in range(self.max_repeats):
yield self.value
return
我试过了,它生成了max_occurrences中指定的项目数
br = BoundedRepeater('tagada', 5)
for item in br:
print(item)
# ->tagada
# ->tagada
# ->tagada
# ->tagada
# ->tagada
第二个示例只给出一次迭代,因为
yield
语句只调用一次,因为\uuuuuuuuuu
只调用一次。\uuu iter\uu
方法不会返回下一个值(因此不会对每个值调用一次),它返回一个包含所有值的迭代器
你可以写
class SmallPrimes:
def __iter__(self):
yield 2
yield 3
yield 5
yield 7
这表明对iter的一次调用包含所有值
在您的情况下,BoundedRepeater
类将把yield
放在for
-循环中:
class BoundedRepeater:
def __init__(self, value, max_repeats):
self.value = value
self.max_repeats = max_repeats
def __iter__(self):
for _ in range(self.max_repeats):
yield self.value
\uuuu iter\uuuu
的执行在每次屈服期间暂停,然后在需要下一个值时恢复。在暂停期间,所有上下文都被保留。请注意,无需跟踪计数变量(self.count
在第一个示例中)
对于您的特定示例(关于将值V重复N次),您不需要编写自己的类。您只需编写一个函数:
def bounded_repeat(V, N):
for _ in range(N):
yield V
for v in bounded_repeat(V, N):
y = do_something(v)
但您不需要编写该函数,因为它已经存在:
import itertools
for v in itertools.repeat(V, N):
y = do_something(v)
但是,除非V很重,N很大,否则只需使用一些好的老Python:
for v in [V] * N:
y = do_something(v)
第二个示例只给出一次迭代,因为
yield
语句只调用一次,因为\uuuuuuuuuu
只调用一次。\uuu iter\uu
方法不会返回下一个值(因此不会对每个值调用一次),它返回一个包含所有值的迭代器
你可以写
class SmallPrimes:
def __iter__(self):
yield 2
yield 3
yield 5
yield 7
这表明对iter的一次调用包含所有值
在您的情况下,BoundedRepeater
类将把yield
放在for
-循环中:
class BoundedRepeater:
def __init__(self, value, max_repeats):
self.value = value
self.max_repeats = max_repeats
def __iter__(self):
for _ in range(self.max_repeats):
yield self.value
\uuuu iter\uuuu
的执行在每次屈服期间暂停,然后在需要下一个值时恢复。在暂停期间,所有上下文都被保留。请注意,无需跟踪计数变量(self.count
在第一个示例中)
对于您的特定示例(关于将值V重复N次),您不需要编写自己的类。您只需编写一个函数:
def bounded_repeat(V, N):
for _ in range(N):
yield V
for v in bounded_repeat(V, N):
y = do_something(v)
但您不需要编写该函数,因为它已经存在:
import itertools
for v in itertools.repeat(V, N):
y = do_something(v)
但是,除非V很重,N很大,否则只需使用一些好的老Python:
for v in [V] * N:
y = do_something(v)
第二个代码应该有一个循环:
用于范围内的(self.max\u repeats):产生self.value
。第二个代码应该有一个循环:用于范围内的(self.max\u repeats):产生self.value
。谢谢你们。我的问题更多地针对底层细节,我想知道为什么在第一个实现的下一个方法中不需要内部循环,而在第二个版本中我确实需要内部循环。我仍然很难理解这一点。因此,如果我理解正确,只有在使用iterable时(例如在for循环中)才会调用iter一次。但在引发异常之前,将调用第一个实现的下一个。全部隐藏在循环语法中。对于具有正确循环语法的yield版本,在iter被调用一次且仅调用一次之后,控制会临时传递回调用站点。然而,在下一次循环迭代时,控制权会返回给iter方法,即使没有显式调用,也会产生下一个值。我没弄错吧?谢谢你们。我的问题更多地针对底层细节,我想知道为什么在第一个实现的下一个方法中不需要内部循环,而在第二个版本中我确实需要内部循环。我仍然很难理解这一点。因此,如果我理解正确,只有在使用iterable时(例如在for循环中)才会调用iter一次。但在引发异常之前,将调用第一个实现的下一个。全部隐藏在循环语法中。对于具有正确循环语法的yield版本,在iter被调用一次且仅调用一次之后,控制会临时传递回调用站点。然而,在下一次循环迭代时,控制权会返回给iter方法,即使没有显式调用,也会产生下一个值。我说对了吗?