zoukankan      html  css  js  c++  java
  • yield生成器函数的一点总结

    生成器有主要有四种方法:

    • next() 执行函数,直到遇到下一个yield为止,并返回值
    • send(value) 为生成器发送一个数值,next()方法就相当于send(None)
    • close() 终止生成器
    • throw(exc[exc_value,[exc_tb]]) 在生成器yield处引发一个异常,close()相当于引发一个GeneratorExit异常

    输出型

    一个斐波那契数列的例子

    def fibonacci():
         a, b = 0, 1
         while True:
             yield b
             a, b = b, a+b
    a = fibonacci()
    for i in range(10):
        print a.next()
    

    运行结果:

    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    python2.7 fb.py  0.01s user 0.01s system 94% cpu 0.025 total
    

    生成器每次生成一个数字并返回。

    接收输入型

    def reciver():
        while True:
            n = (yield)
            print "Got %s" % n
    
    r = reciver()
    r.next()
    r.send(1)
    r.send('2')
    

    运行结果:

    Got 1
    Got 2
    python2.7 rec.py  0.01s user 0.01s system 86% cpu 0.023 total
    

    这个模型可以看做接收外部数据并进行处理。

    输入输出型

    生成器能否接收send传送来的数据,处理之后再返回呢?答案是肯定的

    def get():
        n = 0
        result = None
        while True:
            n = (yield result)
            result = n*10
    
    t = get()
    t.next()
    for i in range(10):
        print t.send(str(i))
    t.close()
    

    运行结果

    0000000000
    1111111111
    2222222222
    3333333333
    4444444444
    5555555555
    6666666666
    7777777777
    8888888888
    9999999999
    python2.7 problem.py  0.02s user 0.00s system 83% cpu 0.024 total
    

    传递参数

    当然生成器函数也是函数,也支持参数传递。

    def countdown(n):
        print("counting down from %d" % n)
        while n > 0:
            yield n
            n -= 1
        return 
    
    c = countdown(10)
    print c.next()
    print c.next()
    
    for i in countdown(10):
        print i
    
    print sum(countdown(10))
    

    运行结果

    counting down from 10
    10
    9
    counting down from 10
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    counting down from 10
    55
    

    从上面的例子我们发现,每次调用生成器函数要先执行next()函数,然后才能发送数据, 如果忘记的话就会报错。

    TypeError: can't send non-None value to a just-started generator
    

    这个有人容易忘记。这怎么办?用装饰器来自动执行:

    def coroutine(func):
        def start(*args,**kwargs):
            g = func(*args,**kwargs)
            g.next()
            return g
        return start
    
    @coroutine
    def reciver():
        while True:
            n = (yield)
            print "Got %s" % n
    
    r = reciver()
    r.send(1)
    r.send('2')
     

    博主ma6174对本博客文章(除转载的)享有版权,未经许可不得用于商业用途。转载请注明出处http://www.cnblogs.com/ma6174/

    对文章有啥看法或建议,可以评论或发电子邮件到ma6174@163.com


  • 相关阅读:
    JQuery选择器
    锋利的jQuery事件
    gitlab
    mac 启动台图标大小调整
    Mac显示和隐藏文件夹
    vs Code 本地服务器配置
    js获取url后带的参数
    路由守卫
    calc()
    Git 本地仓库与远程仓库链接
  • 原文地址:https://www.cnblogs.com/ma6174/p/3018541.html
Copyright © 2011-2022 走看看