浅谈yield from表达式

本篇文章围绕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.value
else:
    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
                break
RESULT = _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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值