浅谈yield from表达式

来源:互联网 发布:python中的open 编辑:程序博客网 时间:2024/05/16 18:45

本篇文章围绕PEP-380提出的yield from表达式内涵开展,并结合python官方关于yield-expression的资料。
在PEP-380的Proposal部分有对yield from表达式的基本阐述。它的格式为yield from expression,其中expression估值后可以是可迭代对象(iterater),但是expression普遍是生成器(generator),一般被称为子生成器(subgenerator)。
子生成器(subgenerator)就像是白手套,帮主人打理事物。它将自己生产的成果直接传递给包含生成器对象(generator object)的方法(method)的调用者。调用者通过调用生成器对象的send()方法传递值给子生成器,子生成器将被传递的值用自己的send()方法处理;调用者通过生成器对象的throw()方法传递异常(exception)给子生成器,子生成器将传递进来的异常用自己的throw()方法处理。如果子生成器没有合适的方法进行相应的处理,调用的send()方法会提起AttributeError异常或TypeError异常,而throw()方法直接提起(raise)被传递的异常。
PEP-380为yield from expression定义了语法规范。以下都是逐条对应翻译的:

  1. 子生成器-迭代器(与本文的子生成器是一个概念,后文一律用子生成器指代)将生产(yield)的值直接传递给调用者。
  2. 任何通过生成器对象send()方法传递的的值都会交给子生成器。如果被传递值是None,子生成器的send()方法被调用。子生成器的send()方法若提起StopIteration异常,则生成器对象被唤醒。任何其他异常都会被传播到调用者。
  3. 被抛入的除GeneratorExit之外的异常会经过子生成器的throw()传递。如果子生成器的throw()方法提起StopIteration异常,生成器被唤醒。任何其他异常都会被传播到调用者。
  4. 如果GeneratorExit异常被抛入生成器,或生成器的close()方法被调用,那么子生成器的close()方法被调用,如果子生成器有该方法的话。如果子生成器的close()方法导致异常,异常会被传播到生成器。否则,GeneratorExit异常在生成器中被提起。
  5. 子生成器终结时提起的StopIteration异常的value属性就是yield from表达式的值。
  6. 如果一个生成器中有return expr语句,那么当从生成器退出时,StopIteration(expr)异常会被提起。

    在该PEP的Formal Semantics提到了使用的3种语法。

    1.RESULT = yield from EXPR语句的等价表现形式:

_i = iter(EXPR)try:    _y = next(_i)except StopIteration as _e:    _r = _e.valueelse:    while True:        try:            _s = yield _y        except GeneratorExit as _e:            try:                _m = _i.close            except AttributeError:                pass            else:                _m()            raise _e        except BaseException as _e:            _x = sys.exc_info()            try:                _m = _i.throw            except AttributeError:                raise _e            else:                try:                    _m(*_x)                except StopIteration as _e:                    _r = _e.value                    break        else:            try:                if _s is None:                    _y = next(_i)                else:                    _y = _i.send(_s)            except StopIteration as _e:                _r = _e.value                breakRESULT = _r

2.在一个生成器函数中return value语句等价于:raise StopIteration(value)

3.StopIteration异常的表现是基于如下定义:

class StopIteration(Exception):    __init__(self,*args):        if len(args) >0:            self.value =args[0]        else:            self.value =None        Exception.__init__(self,*args)
0 0
原创粉丝点击