【问题标题】:How except works for iterators in Python?Python 中的迭代器除外是如何工作的?
【发布时间】:2019-05-08 01:14:21
【问题描述】:

你能解释一下为什么在示例中从未执行过 except 子句并且从未调用过 print 吗?

def h(lst):
  try:
    yield from lst
  except StopIteration:
    print('ST')

t = h([1,2])
next(t)
>>> 1
next(t)
>>> 2
next(t)
>>> Traceback (most recent call last):

File "<ipython-input-77-f843efe259be>", line 1, in <module>
next(t)

StopIteration

【问题讨论】:

    标签: python iterator yield


    【解决方案1】:

    StopIteration 是由next 抛出的,而不是由yield from 抛出的:

    next(iterator[, default])

    通过调用其__next__() 方法从迭代器 中检索下一项。如果给出 default,则在迭代器耗尽时返回,否则引发StopIteration

    因此您可以改为包装 next 调用。

    def h(lst):
        yield from lst
    
    def next_or_print(it):
        try:
            next(it)
        except StopIteration:
            print('ST')
    

    然后你这样使用它:

    >>> t = h([1,2])
    >>> next_or_print(t)
    1
    >>> next_or_print(t)
    2
    >>> next_or_print(t)
    ST
    

    请注意,next 还有第二个参数,允许提供 默认值 而不是 StopIteration

    >>> t = h([1,2])
    >>> next(t, 'ST')
    1
    >>> next(t, 'ST')
    2
    >>> next(t, 'ST')
    ST
    

    【讨论】:

      【解决方案2】:

      您的next 调用在您的h 函数外部,因此不在您的try / except 子句中。为了比较,试试这个:

      def h(lst):
          yield from lst
      
      t = h([1,2])
      

      然后反复运行:

      try:
          print(next(t))
      except StopIteration:
          print('ST')
      

      结果:

      1
      2
      'ST'
      'ST'
      'ST'
      ...
      

      【讨论】:

        【解决方案3】:
        def h(lst):
          try:
            yield from lst
          except StopIteration:
            print('ST')
        t = h([1, 2])
        >>> print(t)
        <generator object h at 0x7fbf6f08aa40>
        

        函数“h”返回一个生成器。作为“return”的语句“yield”什么都不做,只返回一个生成器。异常不会出现在代码的那部分。

        异常必须转移到代码的另一部分,它将在那里工作。

        def h(lst):
            yield from lst
        t = h([1, 2])
        next(t)
        next(t)
        try:
            next(t)
        except StopIteration:
            print('ST')
        ST
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-07
          • 1970-01-01
          • 2014-01-20
          • 1970-01-01
          • 2015-05-20
          • 2011-11-15
          • 2012-08-28
          相关资源
          最近更新 更多