zoukankan      html  css  js  c++  java
  • yield from语法的高级特性

    def gen():
        """子生成器"""
        yield  1
    
    def gen1(gen):
        """委托生成器"""
        yield  from  gen
    
    def main():
        """调用方"""
        g = gen()
        g1 = gen1(g)
        g1.send(None)  # 启动生成器

    上面的代码有3个角色, main是调用方. gen1:委托生成器, gen:子生成器

    yield from会在调用方与子生成器之间建立一个双方通道, 这样,调用方和子生成器之间就可以进行通信(send, close , throw )

    示例

    final_result = {}
    
    
    def sales_num(key):
        total = 0
        nums = []
        while True:
            x = yield  # 使用while循环不断的从调用方接收值
            print(key + '销量:', x)
            if not x:
                break  # 结束while循环
            total += x
            nums.append(x)
        return total, nums # 生成器的值返回到delegate委托生成器中
    
    
    def delegate(key):
        """委托生成器"""
        while True:
            final_result[key] = yield from  sales_num(key)
            print(key + '销量统计完成')
    
    
    def main():
        data_set = {
    
            "欧莱雅": [100, 200, 400],
            "法泉": [12, 4354, 67],
            "死贵人": [212, 23423, 545]
        }
    
        for key, data in data_set.items():
            print('start key:', key)
            d = delegate(key)
            d.send(None)
            for value in data:
                d.send(value)  # 这儿是直接将值send到sales_num子生成器中
            d.send(None) # 结果一个key的统计
        print('final_result:', final_result)
    
    
    if __name__ == '__main__':
        main()

    打印:

    start key: 欧莱雅
    欧莱雅销量: 100
    欧莱雅销量: 200
    欧莱雅销量: 400
    欧莱雅销量: None
    欧莱雅销量统计完成
    start key: 法泉
    法泉销量: 12
    法泉销量: 4354
    法泉销量: 67
    法泉销量: None
    法泉销量统计完成
    start key: 死贵人
    死贵人销量: 212
    死贵人销量: 23423
    死贵人销量: 545
    死贵人销量: None
    死贵人销量统计完成
    final_result: {'欧莱雅': (700, [100, 200, 400]), '法泉': (4433, [12, 4354, 67]), '死贵人': (24180, [212, 23423, 545])}

    补充

    def sales_num(key):
        """定义一个生成器"""
        total = 0
        nums = []
        while True:
            x = yield
            print(key + '销量:', x)
            if not x:
                break  # 结束while循环
            total += x
            nums.append(x)
        return total, nums
    
    
    if __name__ == '__main__':
        g = sales_num("苹果手机")
        g.send(None) # 激活生成器, 也可以使用next(g)
        g.send(5000) #  send一个值到生成器内部, 就是x接收的
        g.send(1000) #  send一个值到生成器内部, 就是x接收的
        g.send(5000) #  send一个值到生成器内部, 就是x接收的
        g.send(None) # 这次send(None) 表过结束生成器,生成器会抛出StopIteration异常,这是个正常的异常,然后返回total, nums
    Traceback (most recent call last):
    苹果手机销量: 5000
      File "E:/ws/python/LearnFlask/test/mooic/yield_test.py", line 21, in <module>
    苹果手机销量: 1000
        g.send(None)
    苹果手机销量: 5000
    StopIteration: (11000, [5000, 1000, 5000])
    苹果手机销量: None
    

      

    为了优雅的结束生成器, 需要try ....  StopIteration....

    下面是优雅的结束生成器的代码

    def sales_num(key):
        """定义一个生成器"""
        total = 0
        nums = []
        while True:
            x = yield
            print(key + '销量:', x)
            if not x:
                break  # 结束while循环
            total += x
            nums.append(x)
        return total, nums
    
    
    if __name__ == '__main__':
        g = sales_num("苹果手机")
        g.send(None) # 激活生成器, 也可以使用next(g)
        g.send(5000) #  send一个值到生成器内部, 就是x接收的
        g.send(1000) #  send一个值到生成器内部, 就是x接收的
        g.send(5000) #  send一个值到生成器内部, 就是x接收的
        try:
            g.send(None) # 这次send(None) 表过结束生成器,生成器会抛出StopIteration异常,这是个正常的异常,然后返回total, nums
        except StopIteration as e:
            print(e.value)  # (11000, [5000, 1000, 5000])  通过异常,获取生成器的返回值
    苹果手机销量: 5000
    苹果手机销量: 1000
    苹果手机销量: 5000
    苹果手机销量: None
    (11000, [5000, 1000, 5000])

    通过上面的yield from示例可知,yield from帮我们处理了try...stopiteration...异常, 因为我们并没有手动去处理.

  • 相关阅读:
    TP框架基础
    PHP文件上传
    layui-简单的登录注册界面
    layui-注册界面
    JavaScript原生Ajax请求纯文本数据
    ajax异步请求数据
    PHP数据库连接
    PHP页面跳转以及伪登录实例
    OVER 分析函数
    Ubuntu 16 vi输入方向键会变成ABCD的解决方法
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/12109960.html
Copyright © 2011-2022 走看看