我可以使方法成为生成器而不是返回生成器吗?

Can I make a method BE a generator instead of RETURNING one?

我希望对象的方法是 returns 每次调用内部列表中的新元素,直到它返回所有元素(但它本身是不可变的)。

虽然我可以存储例如列表中最后查看的元素的索引,我希望对象是不可变的,这样解决方案就出来了。 我想在这里使用生成器,但我不知道如何编写它,以便该方法实际上是生成器,而不是返回一个生成器。而且我想从不同的地方访问它,而不是在一个地方的一个循环中,所以我不想每次都需要一个新的生成器。

我试过了:

class Node:
    def __init__(up, right, down, left):
        self.up = up
        self.right = right
        self.down = down
        self.left = left

    def get_next_neighbour(self):
        for neighbour in [self.up, self.right, self.down, self.left]:
            if neighbour is not None:
                yield neighbour

我试过这样访问它:

n = Node(1, 2, 3, 4)
next_neighbour = next(n.get_next_neighbour()) # returns 1

然后,在完全不同的代码部分,但对象相同:

next_neighbour = next(n.get_next_neighbour()) # returns 1 again, while I want 2

我意识到 get_next_neighbour() returns 每次都是一个新的生成器,所以这就是为什么我总是得到 1。我只希望 get_next_neighbour() 本身表现出它的实际生成器returns。我希望我在这里说得通:\

每次调用函数 returns 一个新的生成器,当然。 (该函数仍然是生成器,但它只是在每次调用时重新初始化。)

如果你真的想共享生成器的状态,你可以这样拆分,也许,并存储正在进行的生成器。

class Node:
    def __init__(self, up, right, down, left):
        self.up = up
        self.right = right
        self.down = down
        self.left = left
        self._neighbor_generator = None

    def _get_next_neighbour(self):
        print('Initialized new generator.')
        for neighbour in [self.up, self.right, self.down, self.left]:
            if neighbour is not None:
                yield neighbour
        self._neighbor_generator = None  # next call will create a new generator

    def get_next_neighbour(self):
        if not self._neighbor_generator:
            self._neighbor_generator = self._get_next_neighbour()
        return self._neighbor_generator

n = Node(1, 2, 3, 4)
for x in range(10):
    print(next(n.get_next_neighbour(), None))

产出

Initialized new generator.
1
2
3
4
None
Initialized new generator.
1
2
3
4
None

这看起来有点像 XY 问题

而不是:

  1. 初始化:

    n = Node(1, 2, 3, 4)
    
  2. 用法(在代码的不同部分):

    next_neighbour = next(n.get_next_neighbour())
    

,你可以这样做:

  1. 初始化:

    n = Node(1, 2, 3, 4)
    neighbours = n.get_next_neighbour()
    
  2. 用法:

    next_neighbour = next(neighbours)
    

:

  • 我确定这只是一个错字,但您应该将初始化程序修改为:

    def __init__(self, up, right, down, left):  # self is missing