生成器

参考文章:  协程   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. /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t7.thread..py

hehe 

可以看出

  • 生成器的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. /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t7.thread..py
[PRODUCER] Producing ...
[CONSUMER] Consuming ...
[PRODUCER] Consumer return: OK
[PRODUCER] Producing ...
[CONSUMER] Consuming ...
[PRODUCER] Consumer return: OK
[PRODUCER] Producing ...
[CONSUMER] Consuming ...
[PRODUCER] Consumer return: OK
[PRODUCER] Producing ...
[CONSUMER] Consuming ...
[PRODUCER] Consumer return: OK
[PRODUCER] Producing ...
[CONSUMER] Consuming ...
[PRODUCER] Consumer return: OK Process finished with exit 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. /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/
bytes received from https://www.baidu.com/.
bytes received from https://www.liaoxuefeng.com/.
bytes received from https://www.cnblogs.com/dahu-daqing/. Process finished with exit code

python生成器 协程的更多相关文章

  1. python中和生成器协程相关的yield from之最详最强解释,一看就懂(四)

    如果认真读过上文的朋友,应该已经明白了yield from实现的底层generator到caller的上传数据通道是什么了.本文重点讲yield from所实现的caller到coroutine的向下 ...

  2. python中和生成器协程相关yield from之最详最强解释,一看就懂(二)

    一. 从列表中yield  语法形式:yield from <可迭代的对象实例> python中的列表是可迭代的, 如果想构造一个生成器逐一产生list中元素,按之前的yield语法,是在 ...

  3. python中和生成器协程相关的yield之最详最强解释,一看就懂(一)

    yield是python中一个非常重要的关键词,所有迭代器都是yield实现的,学习python,如果不把这个yield的意思和用法彻底搞清楚,学习python的生成器,协程和异步io的时候,就会彻底 ...

  4. python gevent 协程

    简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...

  5. 关于Python的协程问题总结

    协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生 ...

  6. {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二

    python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...

  7. 【Python】协程

    协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在 ...

  8. 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!

    本文参考:http://www.dabeaz.com/coroutines/   作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...

  9. Python之协程(coroutine)

    Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...

随机推荐

  1. Stanford机器学习---第十四讲.机器学习应用举例之Photo OCR

    http://blog.csdn.net/l281865263/article/details/50278745 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归.Oc ...

  2. python访问需要登录的网页

    有些网页需要你登录之后才可以访问,你需要提供账户和密码. 只要在发送http请求时,带上含有正常登陆的cookie就可以了. 1.首先我们要先了解cookie的工作原理. Cookie是由服务器端生成 ...

  3. Linux iptables:规则组成

    <Linux iptables:规则原理和基础>介绍了iptables的四表五链,简单说就是不同的网络层数据包会经过哪几个挂载点,在每个挂载点可以在哪张表进行规则定义. 本篇沿着这个思路, ...

  4. scp 从本地往线上传文件

    scp /home/wwwroot/default/tf_ment.sql root@IP:/home/wwwroot/default/

  5. 「Linux」centos7安装python

    •安装python3.6可能使用的依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqli ...

  6. ndk如何将代码放在jni之外

    LOCAL_PATH := $(call my-dir)SDK_PATH := ../../.. include $(CLEAR_VARS)LOCAL_MODULE := libiconv_stati ...

  7. HDU 1812 polya 大数

    由于反射的存在,分奇偶讨论其置换的循环节数量,大数用JAVA就好了. import java.math.*; import java.util.*; public class Main{ public ...

  8. ASP.NET站点Web部署(一键发布的实现)

    在开发过程中经常需要发布到开发环境.测试环境或者预发布环境上给其他同事进行测试验证效果等等,每次发布都要备份,拷贝,修改配置文件等等重复操作非常的麻烦,效率大打折扣,而web部署提供了这样的解决方案: ...

  9. 强制换行CSS样式

    语法: word-wrap : normal | break-word 取值: normal :? 默认值.允许内容顶开指定的容器边界 break-word :? 内容将在边界内换行.如果需要,词内换 ...

  10. Try finally的一个实验和为什么避免重载 finalize()方法--例子

    public class TryFinallTest { public TryFinallTest(){ } public void runSomething(String str){ System. ...