我可以使方法成为生成器而不是返回生成器吗?
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 问题。
而不是:
初始化:
n = Node(1, 2, 3, 4)
用法(在代码的不同部分):
next_neighbour = next(n.get_next_neighbour())
,你可以这样做:
初始化:
n = Node(1, 2, 3, 4)
neighbours = n.get_next_neighbour()
用法:
next_neighbour = next(neighbours)
注:
我确定这只是一个错字,但您应该将初始化程序修改为:
def __init__(self, up, right, down, left): # self is missing
我希望对象的方法是 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 问题。
而不是:
初始化:
n = Node(1, 2, 3, 4)
用法(在代码的不同部分):
next_neighbour = next(n.get_next_neighbour())
,你可以这样做:
初始化:
n = Node(1, 2, 3, 4) neighbours = n.get_next_neighbour()
用法:
next_neighbour = next(neighbours)
注:
我确定这只是一个错字,但您应该将初始化程序修改为:
def __init__(self, up, right, down, left): # self is missing