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

时间:2019-06-22 12:12:30

标签: python python-3.x generator python-3.7 yield

我想拥有一个对象,该对象的方法每次调用时都会从内部列表中返回一个新元素,直到返回所有元素为止(但本身是不可变的)。

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

我尝试过:

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()每次都会返回一个新的生成器,所以这就是为什么我总是得到1。我只希望get_next_neighbour()本身表现出它返回的实际生成器。我希望我在这里有意义:\

2 个答案:

答案 0 :(得分:1)

当然,每次调用该函数都会返回一个新的生成器。 (该函数仍然是生成器,但每次调用都会重新初始化。)

如果您确实希望共享生成器的状态,则可以拆分这样的内容,然后将生成器存储在进程中。

<div class="header">
  <div class="first">
    <div class="logo">Image</br>here</div>
</div>  
    
    <div class="right">
      <div class="welcome">Welcome to here</div>
      
      <div class="links">
      <ul class="menu">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
<li><a href="#">Link 4</a></li>
<li><a href="#">Link 5</a></li>
      </ul>
      </div>
    </div>
    
    

  
</div><!--header-->

输出

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))

答案 1 :(得分:1)

这看起来有点像 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