Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 作为迭代器成员函数的生成器_Python_Iterator - Fatal编程技术网

Python 作为迭代器成员函数的生成器

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

因此我理解,有时候,在一个类中定义iternext方法,而不是应该是可iterable的,只使用包含yield语句的iter方法就足够了。为什么呢?只是要避免样板代码

然而,我不明白为什么下面的代码片段会产生三次迭代

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方法,即使没有显式调用,也会产生下一个值。我说对了吗?