2.3.2-2.3.11生成器以及协程gevent介绍

本文详细介绍了Python中的生成器和协程,包括生成器的两种创建方法,yield关键字的作用,send唤醒生成器的机制,以及协程的基本概念和实现方式。此外,还讲解了greenlet和gevent库在协程中的应用,以及协程与进程、线程的对比,强调了协程的高效性和资源利用率。
摘要由CSDN通过智能技术生成

1、生成器:是一类特殊的迭代器。
1)创建生成器的方法1:只要把一个列表生成式的 [ ] 改成 ( ),对于生成器G,我们可以按照迭代器的使用方法来使用,即可以通过next()函数、for循环、list()等方法使用。
In [17]: G = ( x*2 for x in range(5))
In [18]: G
Out[18]: <generator object at 0x7f626c132db0>
2)创建生成器方法2:在使用生成器实现的方式中,我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现,将每次迭代返回数值的return换成yield,此时新定义的函数便不再是函数,而是一个生成器。简单来说:只要在def中有yield关键字的 就称为 生成器

总结
1)使用了yield关键字的函数不再是函数,而是生成器。(使用了yield的函数就是生成器)
2)yield关键字有两点作用:
a. 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
b. 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
3)可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)
4)Python3中的生成器可以使用return返回最终运行的返回值,而Python2中的生成器不允许使用return返回一个返回值(即可以使用return从生成器中退出,但return后不能有任何表达式)。

2、使用send唤醒:除了可以使用next()函数来唤醒生成器继续执行外,还可以使用send()函数来唤醒执行。使用send()函数的一个好处是可以在唤醒的同时向断点处传入一个附加数据。

3、协程-yield:协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。 通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。
简单实现协程
import time

def work1():
while True:
print("----work1—")
yield
time.sleep(0.5)

def work2():
while True:
print("----work2—")
yield
time.sleep(0.5)

def main():
w1 = work1()
w2 = work2()
while True:
next(w1)
next(w2)

if name == “main”:
main()

4、协程-greenlet(人工切换协程)
使用如下命令安装greenlet模块:
sudo pip3 install greenlet

#coding=utf-8
from greenlet import greenlet
import time

def test1():
while True:
print “—A–”
gr2.switch()
time.sleep(0.5)

def test2():
while True:
print “—B–”
gr1.switch()
time.sleep(0.5)

gr1 = greenlet(test1)
gr2 = greenlet(test2)

#切换到gr1中运行
gr1.switch()

5、协程-gevent(自动切换协程)
安装
pip3 install gevent
1)gevent的使用
import gevent

def f(n):
for i in range(n):
print(gevent.getcurrent(), i)

g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)
g1.join()
g2.join()
g3.join()

2)gevent切换执行

import gevent

def f(n):
for i in range(n):
print(gevent.getcurrent(), i)
#用来模拟一个耗时操作,注意不是time模块中的sleep
gevent.sleep(1)

g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)
g1.join()
g2.join()
g3.join()

6、进程、线程、协程对比
简单总结
1)进程是资源分配的单位
2)线程是操作系统调度的单位
3)进程切换需要的资源很最大,效率很低
4)线程切换需要的资源一般,效率一般(当然了在不考虑GIL的情况下)
5)协程切换任务资源很小,效率高
6)多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中 所以是并发

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值