协程总结

一、迭代器
1.迭代:
对list、tuple、str等类型的数据使用for...in...的循环语法从其中依次拿到数据进行使用,
这个过程称为遍历,也叫迭代。


2.可迭代对象:
凡是可以通过for...in...这类语句迭代读取一条数据供我们使用的对象称之为可迭代对象(Iterable)。


3.迭代器:
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,
迭代器会向我们返回它所记录位置的下一个位置的数据。
一个实现了__iter__方法和__next__方法的对象,就是迭代器。
只实现了__iter__方法的对象是可迭代对象


4.判断一个对象是否为迭代器或是可迭代对象:
from collections import Iterable, Iterator

isinstance(对象名,Iterator)迭代器
isinstance(对象名,Iteratable)可迭代对象


5.对象迭代过程:
可迭代对象通过iter()方法向我们提供一个迭代器,
我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值,
当遇到StopIteration的异常后循环结束。

6.除了for循环能接收可迭代对象,list、tuple等也能接收:
li = list()
tp = tuple()

7.迭代器的创建方法:
1.为容器对象添加 __iter__() 和 __next__() 方法(Python 2.7 中是 next());
__iter__() 返回迭代器对象本身 self,
__next__() 则返回每次调用 next() 或迭代时的元素。
2.使用内置函数 iter() 将可迭代对象转化为迭代器
3.生成器


二、生成器
1.生成器是迭代器的一种创建方式,也可以说是一种特殊的迭代器
生成器的定义方法:
1.生成器表达式: 把一个列表生成式(列表推导式)的 [ ] 改成 ( )
2.生成器函数: 加了yield的函数


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


三、协程(重点)
1. 协程(yield关键字是重点):
在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行。
(注意:不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定)
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)


2.程序、进程、线程、协程(面试重点):


程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念;
进程是程序在处理机上的一次执行过程,它是一个动态的概念;
程序可以作为一种软件资料长期存在;而进程是有一定生命期的,是暂时的;

线程是最小的执行单元,而进程由至少一个线程组成;
多进程中,每个进程中所有数据(包括全局变量)都各有拥有一份,互不影响;
多线程中,所有线程共享进程的内存。

协程,只使用一个线程,分解一个线程成为多个“微线程”,在一个线程中规定某个代码块的执行顺序。
线程和进程的操作是由程序触发系统接口,最后的执行者是系统,它本质上是操作系统提供的功能。
而协程的操作则是程序员指定的,在python中通过yield,人为的实现并发处理。


3.协程_greenlet:
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()


实际上,greenlet就是通过switch方法在不同的任务之间进行切换。

4.协程_gevent:


from gevent import monkey
import gevent
import urllib.request
import random
import time


# 有耗时操作时需要
monkey.patch_all()  # 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块


def coroutine_work(coroutine_name):
for i in range(10):
print(coroutine_name, i)
time.sleep(random.random())


gevent.joinall([
gevent.spawn(coroutine_work, "work1"),
gevent.spawn(coroutine_work, "work2")
])


通过joinall将任务和它的参数进行统一调度,实现单线程中的协程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值