zoukankan      html  css  js  c++  java
  • python生成器 协程

    生成器

    参考文章:  协程   gevent

    生成器进阶

    看个例子:

    def gg():
        n=''
        i=0
        while True:
            n=yield i   #通过send传入到n
            if not n:
                pass
            else:
                print 'hehe',n
                i=100   #传进参数n的时候,使得i的值也变化了
            i+=1
    if __name__=='__main__':
        a=gg()
        print a.send(None)
        print a.next()
        print a.send(None)
        print a.send(9)
        print a.next()
        a.close()

    结果:

    /usr/bin/python2.7 /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t7.thread.4.py
    0
    1
    2
    hehe 9
    101
    102

    可以看出

    • 生成器的send(None)方法等于next()方法,next()方法可以直接替换成for循环
    • 通过send(n)传递参数n进生成器,生成器里面通过yield关键字来获取参数的值

    协程

    我们利用这个特性,来学习一下协程

    #!/usr/bin/python
    # coding=utf-8
    # __author__='dahu'
    # data=2017-
    #多线程更改变量
    import time
    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            time.sleep(0.5)
            r = '200 OK'
    def produce(c):
        c.next()
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            r = c.send(n)       #给生成器里传参,同时获取生成器里的值
            print('[PRODUCER] Consumer return: %s' % r)
        c.close()
    if __name__=='__main__':
        c = consumer()
        produce(c)

    结果,

    /usr/bin/python2.7 /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t7.thread.4.py
    [PRODUCER] Producing 1...
    [CONSUMER] Consuming 1...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 2...
    [CONSUMER] Consuming 2...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 3...
    [CONSUMER] Consuming 3...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 4...
    [CONSUMER] Consuming 4...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 5...
    [CONSUMER] Consuming 5...
    [PRODUCER] Consumer return: 200 OK
    
    Process finished with exit code 0
    View Code

    注意到consumer函数是一个generator(生成器),把一个consumer传入produce后:

    1. 首先调用c.next()启动生成器;

    2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

    3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

    4. produce拿到consumer处理的结果,继续生产下一条消息;

    5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

    gevent

    Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。

    gevent是第三方库,通过greenlet实现协程,其基本思想是:

    当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

    由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成

    直接看例子:

    #!/usr/bin/python
    #coding=utf-8
    #__author__='dahu'
    #data=2017-
    from gevent import monkey; monkey.patch_all()
    import gevent
    import urllib2
    def f(url):
        print('GET: %s' % url)
        resp = urllib2.urlopen(url)
        data = resp.read()
        print('%d bytes received from %s.' % (len(data), url))
    
    gevent.joinall([
            gevent.spawn(f, 'https://www.cnblogs.com/dahu-daqing/'),
            gevent.spawn(f, 'https://www.liaoxuefeng.com/'),
            gevent.spawn(f, 'https://www.baidu.com/'),
    ])

    结果:  从结果看,3个网络操作是并发执行的,而且结束顺序不同,但只有一个线程。

    /usr/bin/python2.7 /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t10.gevent.py
    GET: https://www.cnblogs.com/dahu-daqing/
    GET: https://www.liaoxuefeng.com/
    GET: https://www.baidu.com/
    227 bytes received from https://www.baidu.com/.
    38708 bytes received from https://www.liaoxuefeng.com/.
    48289 bytes received from https://www.cnblogs.com/dahu-daqing/.
    
    Process finished with exit code 0
  • 相关阅读:
    “main cannot be resolved or is not a field”解决方案
    .net学习笔记----有序集合SortedList、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>
    MVC学习笔记---ModelBinder
    MVC学习笔记---MVC框架执行顺序
    服务器知识----IIS架设问题
    C/C++学习笔记---primer基础知识
    C/C++学习笔记----指针的理解
    C#学习笔记-----C#枚举中的位运算权限分配
    CSS学习笔记----CSS3自定义字体图标
    Clr Via C#读书笔记----基元线程同步构造
  • 原文地址:https://www.cnblogs.com/dahu-daqing/p/7413581.html
Copyright © 2011-2022 走看看