python协程

一、迭代器

\qquad 1、解释:迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。简单来说可迭代对象是可以直接使用for循环的对象。迭代器
\qquad 2、判断数据类型是否可迭代。
\qquad 判断某一数据类型是否可迭代,可使用isinstance()判断一个对象是否为可迭代对象。

from collections import Iterable

a = isinstance([],Iterable)
b = isinstance((),Iterable)
c = isinstance("asdfg",Iterable)
d = isinstance(100,Iterable)
print([a,b,c,d])

\qquad 代码结果解释:最后输出的结果是[True,True,True,False],说明列表,数组,字符串都属于可迭代对象,而数值不属于可迭代对象。
\qquad 可以被next()函数调用并不断返回下一个值的对象称为迭代器。可以使用isinstance()判断一个对象是否为迭代器。

from collections import Iterator
a = isinstance((x for x in range(10)),Iterator)
b = isinstance([],Iterator)
c = isinstance((),Iterator)
d = isinstance("asdf",Iterator)
print([a,b,c,d])

\qquad 运行结果及解释:运行结果为[True,Flase,False,False],说明列表,数组,字符串属于可迭代对象,但不是迭代器。
\qquad 3、实现可迭代对象

import time

class Classmate(object):
	def __init__(self):
		self.names = list()

	def add(self,name):
		self.names.append(name)

	def __iter__(self):
		return classIterator(self)

class classIterator(object):
	def __init__(self,obj):
		self.obj = obj
		self.corrent_num = 0

	def __iter__(self):
		pass

	def __next__(self):
		if self.corrent_num<len(self.obj.names):
			ret = self.obj.names[self.corrent_num]
			self.corrent_num+=1
			return ret
		else:
			raise StopIteration

classmate = Classmate()
classmate.add("wanger")
classmate.add("zhangsan")
classmate.add("lisi")
for name in classmate:
	print(name)
	time.sleep(1)

\qquad 迭代器的优点:只提供迭代的方式,在迭代的时候才调用迭代的数据,节省了空间。

二、生成器

\qquad 1、定义:生成器是一次生成一个值的特殊类型函数。可以将其视为可恢复函数。调用该函数将返回一个可用于生成连续 x 值的生成器。简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候又从上次中断的地方开始执行,而生成器内的所有变量参数都会被保存下来供下一次使用。生成器是一种特殊的迭代器。
\qquad 2、创建生成器的方法
\qquad 方法一:列表生成式的 [ ] 改成( )

num = [x for x in range(10)]
num
nums = (x for x in range(10))
nums

\qquad 运行结果及解释:num是一个列表,nums是一个生成器。
\qquad 方法二:在定义函数时使用yeild。

def fib(num):
    num1,num2 = 0,1
    current_num = 0
    while current_num<num:
        #如果一个函数出现yield,那么这个函数不再时一个函数,而是一个生成器mu'ba
        yield num1
        num1,num2 = num2,num1+num2
        current_num+=1
#调用函数时,发现函数中有yield,则不再是调用函数,而是创建一个生成器
fib(10)

三、使用协程实现多任务

$\qquad$1、使用yield完成多任务

import time

def task1():
    while True:
        print("---1---")
        time.sleep(1)
        yield

def task2():
    while True:
        print("---2---")
        time.sleep(1)
        yield
        
def main():
    t1 = task1()
    t2 = task2()
    while True:
        next(t1)
        next(t2)

if __name__ == "__main__":
    main()

$\qquad$2、使用greenlet完成多任务

from greenlet import greenlet
import time

def task1():
    while True:
        print("---1---")
        gr2.switch()
        time.sleep(1)
        
def task2():
    while True:
        print("---2---")
        gr1.switch()
        time.sleep(1)
        
gr1 = greenlet(task1)
gr2 = greenlet(task2)

gr1.switch()

\qquad 3、使用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()

\qquad 代码运行后结果是并不是实行多任务,而是一个任务一个任务地完成。所以需要延时操作才能完成多任务,但gevent所有地延时操作必须使用gevent模块里的延时操作。或者创造补丁,使得所有延时操作自动转换成gevent模块的延时操作。

import gevent
import time
from gevent import monkey

monkey.patch_all()

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

g1 = gevent.spawn(f,5)
g2 = gevent.spawn(f,5)
g3 = gevent.spawn(f,5)
g1.join()
g2.join()
g3.join()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值