什么是协程?
协程,又称微线程,纤程。英文名Coroutine。协程,利用线程在等待某个资源的期间执行其他函数,切换资源消耗非常小,协程效率相当快。
进程、线程和协程的区别?
进程是资源分配的单位,真正执行代码的是线程,操作系统真正调度的是线程。
进程没有线程效率高,进程占用资源多,线程占用资源少,比线程更少的是协程。
协程依赖于线程、线程依赖于进程,进程一死线程必挂,线程一挂协程必死
一般不用多进程,可以考虑使用多线程,如果多线程里面有很多网络请求(耗时操作),网络可能会有堵塞,此时用协程比较合适。
可迭代对象:
1.通过for ... in ...
2.一个对象里边只要有__iter__方法就是一个可迭代对象
3.isinstance(对象名,Iterable)---返回True就是一个可迭代对象
迭代器
1.一个对象中实现了__iter__方法和__next__方法,那么它就是一个迭代器
2.iter()---获取可迭代对象的迭代器-------> iter(可迭代对象)--自动执行可迭代对象中的__iter__方法
3.rais StopIteratioin ---遇到StopIteration的异常后循环结束。
4.迭代器=iter(可迭代对象)----->isinstance(迭代器,Iterator)
5.next(迭代器)--next方法的返回值
迭代器的应用
目的:能实现很多数据,又不用太多内存空间
优点:什么时候生成,什么时候调用,减少内存空间,方便使用
生成器
1.由列表推导式变为生成器:nums = [i*2 for i in range(10)]------>nums = (i*2 for i in range(10))
2.如果一个函数中有yield语句,那么这个就不再是函数,而是一个生成器模板
3.如果调用函数的时候,发现这个函数中有yield那么此时,不是调用函数,而是创建一个生成器对象
4.yield作用:让程序暂停执行,下一次还从yield开始;yield 的返回值 = next(生成器对象)
5.要想启动生成器,需要用:next(生成器对象);也可以用send(),进行传值
6.send和next的区别:send可以传参,next不可以传参
7.生成器是一种特殊的迭代器,可以让程序暂停执行,并返回当前值
生成器的应用
yield实现多任务
import time
def task_1():
while True:
print("---1---")
time.sleep(0.1)
yield
def task_2():
while True:
print("---2---")
time.sleep(0.1)
yield
def main():
t1 = task_1()
t2 = task_2()
while True:
next(t1)
next(t2)
if __name__ == '__main__':
main()
greenlet:greenlet创建的对象可以调用 switch( )进行切换,达到多任务
gevent:
特点:遇到延时自动切换,实现多任务
案例-并发下载器
import gevent
import urllib.request
# from gevent import monkey
# monkey.patch_all()
def download_img(img_name,img_url):
req=urllib.request.urlopen(img_url)
content=req.read()
with open(img_name, "wb") as f:
f.write(content)
def main():
gevent.joinall([
gevent.spawn(download_img,"/home/python/Desktop/3.jpg", "https://wx1.sinaimg.cn/mw690/006HBWQXly1fu9p2avkhaj307i0b9gmc.jpg"),
gevent.spawn(download_img,"/home/python/Desktop/4.jpg", "https://wx1.sinaimg.cn/large/007vLMz8ly1g1o9e1ioa0j3067089weq.jpg")
])
if __name__ == '__main__':
main()
案例--并发下载器