说说 yield from

简述

每当看到yield from,都有些心虚,因为不了解。今天找时间了解了一下,不得不说官网的英语太难了,哎~,先把看懂的说下一吧

为啥用yield from呢
  • 第一个理由
RESULT = yield from EXPR

上面的代码是等于下面的代码的

#### 工作代码
_i = iter(EXPR)
try:
    _y = next(_i)
except StopIteration as _e:
    _r = _e.value
else:
    while 1:
        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:
                    _y = _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

也就是说用了yield from,我们不用写这么多代码来解决异常的情况了

  • 第二个理由
    yield from 帮我们做了迭代
def generator_one():
    local_list = ["one", "two", "three"]
    yield from local_list


if __name__ == "__main__":
    test_one = generator_one()
    for temp_part in test_one:
        print(temp_part)

上面的代码等于

def generator_one():
    local_list = ["one", "two", "three"]
    for part in local_list:
        yield part


if __name__ == "__main__":
    test_one = generator_one()
    for temp_part in test_one:
        print(temp_part)
yield from的几个特点
  • yield from后面接的表达式,返回的值是直接发送给调用者的。这个特点比较绕,我试着解释一下。我们从上面的原理代码中可以看出迭代器产生的值,最终还是被yield修饰,也就是当我们在print(test_two.send(1))这样的类似语句调用,yield from的生成器时,最终调用的还是迭代器的__next__()方法取值。
    运行一下下面的代码,你会发现print("Is Over")是一直不运行的,也就是说print(test_two.send(1))语句调用的是generator_one返回的生成器
def generator_one():
    local_list = ["one", "two", "three"]
    for part in local_list:
        yield part


def generator_two():
    while True:
        yield from generator_one()
        print("Is Over")


if __name__ == "__main__":
    test_two = generator_two()
    print(type(test_two))
    print(test_two.send(None))
    print(test_two.send(1))
    print(test_two.send(1))
  • 如果除了GeneratorExit 之外的异常,传给了yield from,那么迭代器的throw()方法将被调用,对应原理代码中的_i.close

  • 如果GeneratorExit 或者生成器调用了close()方法,那么迭代器的close()方法将被调用,对应原理代码中的_i.throw

推荐一个大哥写的文章,关于yield from的

https://www.lagou.com/lgeduarticle/75809.html


如果对本文有疑问或者发现不对的地方,希望能给予评论或者进群630300475,讨论一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值