【问题标题】:How to yield from __next__ method?如何从 __next__ 方法产生?
【发布时间】:2019-05-09 07:10:09
【问题描述】:

我认为下面的代码会表达想要的结果:

class LockIterator(object):

    def __init__(self, lock_list):
        self.lock_list = lock_list

    def __iter__(self):
        return self

    def __next__(self):

        for resource in self.lock_list:
            print( "Locking N resources" )

            yield resource
            print( "Unlocking N resources" )

        print( "Unlocking remaining resources" )
        raise StopIteration


for item in LockIterator( ["Resource 1", "Resource 2", "Resource 3"] ):
    print("Safe resource usage:", item)

但是,在 Python 上运行它,我得到了一个无限循环:

Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BDA24938>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BB8AEE60>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BDA24938>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BB8AEE60>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BDA24938>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BB8AEE60>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BDA24938>
Safe resource usage: <generator object LockIterator.__next__ at 0x000001A8BB8AEE60>
...

在我的想象中,它应该是这样运行的:

Locking N resources
Safe resource usage: Resource 1
Unlocking N resources
Locking N resources
Safe resource usage: Resource 2
Unlocking N resources
Locking N resources
Safe resource usage: Resource 3
Unlocking N resources
Unlocking remaining resources

您知道如何在普通的 for 循环中自动强制执行此行为吗?

for item in LockIterator( ["Resource 1", "Resource 2", "Resource 3"] ):
    print("Safe resource usage:", item)

【问题讨论】:

    标签: python-3.x for-loop iterator generator yield


    【解决方案1】:

    __next__ 在每次 for 循环需要一个新项目时被调用。因为你的__next__ 是一个生成器,所以每次都会返回。

    相反,你可以去掉这个类,只写一个生成器:

    def LockIterator(lock_list):
        # better name this lockify or something else in snake_case
        for resource in lock_list:
            print("Locking N resources")
    
            yield resource
            print("Unlocking N resources")
    
        print("Unlocking remaining resources")
    

    【讨论】:

      【解决方案2】:

      我还设法通过删除 __next__ 并将其主体移动到 __iter__ 方法来修复它:

      class LockIterator(object):
      
          def __init__(self, lock_list):
              self.lock_list = lock_list
      
          def __iter__(self):
      
              for resource in self.lock_list:
                  print( "Locking N resources" )
      
                  yield resource
                  print( "Unlocking N resources" )
      
              print( "Unlocking remaining resources" )
      
      for item in LockIterator( ["Resource 1", "Resource 2", "Resource 3"] ):
          print("Safe resource usage:", item)
      

      【讨论】:

        猜你喜欢
        • 2019-02-02
        • 2018-12-31
        • 1970-01-01
        • 2012-09-15
        • 2011-08-24
        • 1970-01-01
        • 2017-03-08
        • 2017-07-29
        • 2012-06-10
        相关资源
        最近更新 更多