多线程--协程
Posted zach0812
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程--协程相关的知识,希望对你有一定的参考价值。
---恢复内容开始---
迭代器:
常用的可以迭代的类型:
1 from collections import Iterable 2 print(issubclass(int,Iterable)) #False 3 print(issubclass(float,Iterable)) #False 4 print(issubclass(list,Iterable)) #True 5 print(issubclass(tuple,Iterable)) #True 6 print(issubclass(dict,Iterable)) #True 7 print(issubclass(str,Iterable)) #True 8 print(issubclass(set,Iterable)) #True
下面尝试自己写个可以迭代的类出来:
1 class ClassMate: 2 def __init__(self): 3 self.names = list() 4 5 def add(self,name): 6 self.names.append(name) 7 8 if __name__ == ‘__main__‘: 9 classmate = ClassMate() 10 classmate.add("tom") 11 classmate.add("jane") 12 classmate.add("egon") 13 14 for name in classmate: #报错,此时是不可以迭代的 15 print(name)
此时的报错: TypeError: ‘ClassMate‘ object is not iterable
继续:
1 class ClassMate: 2 def __init__(self): 3 self.names = list() 4 5 def add(self,name): 6 self.names.append(name) 7 8 def __iter__(self): 9 pass 10 11 if __name__ == ‘__main__‘: 12 classmate = ClassMate() 13 classmate.add("tom") 14 classmate.add("jane") 15 classmate.add("egon") 16 17 for name in classmate: #此时是不可以迭代的 18 print(name) 19 20 #此时的报错是:TypeError: iter() returned non-iterator of type ‘NoneType‘
但是,此时它已经是个可迭代的对象了,使用如下代码验证:
print(issubclass(ClassMate,Iterable))
所以:
但是,还是用不了for 循环。
继续看:
只要使__iter__() 方法返回一个有iter 和next 方法的对象就行了!
for 循环的执行过程,
for 循环得到的是返回的对象里的__next__() 返回的值!
1 from collections import Iterable,Iterator 2 3 class ClassMate: 4 def __init__(self): 5 self.names = list() 6 7 def add(self,name): 8 self.names.append(name) 9 10 def __iter__(self): 11 # pass #必须要返回一个具有 iter 和 next 方法的对象 12 return MyIterator() 13 14 15 class MyIterator: 16 def __iter__(self): 17 pass 18 def __next__(self): 19 pass 20 21 22 if __name__ == ‘__main__‘: 23 classmate = ClassMate() 24 classmate.add("tom") 25 classmate.add("jane") 26 classmate.add("egon") 27 28 #判断 classmate 是否是可迭代对象 29 # print(isinstance(classmate,Iterable)) #只要是有对象iter() 方法就行,就是可迭代对象 30 31 32 myiterator = iter(classmate) #它返回的是MyIterator 的对象 ,它是个迭代器 33 #判断myiterator 是否是迭代器 34 # print(isinstance(myiterator,Iterator)) true #迭代器要满足iter() 和next() 都有
理论上,此时已经可以运行,但是,迭代器中的next 中还需要一些处理:
1 from collections import Iterable,Iterator 2 import time 3 4 class ClassMate: 5 def __init__(self): 6 self.names = list() 7 8 def add(self,name): 9 self.names.append(name) 10 11 def __iter__(self): 12 # pass #必须要返回一个具有 iter 和 next 方法的对象 13 return MyIterator() 14 15 16 class MyIterator: 17 def __iter__(self): 18 pass 19 def __next__(self): 20 return 11 21 22 23 24 if __name__ == ‘__main__‘: 25 classmate = ClassMate() 26 classmate.add("tom") 27 classmate.add("jane") 28 classmate.add("egon") 29 30 for name in classmate: 31 print(name) 32 time.sleep(1) #这时的输出是 每1s 打印一遍11 33
每秒打印11 ,也验证了上面的说法,for name in classmate 时,
首先判断classmate 是否可迭代(__iter__())
继续,判断classmate 中的__iter__() 的返回值是否是个迭代器(对象有 __iter__() __next__())
最后,得到的name 就是 迭代器对象中的__next__() 方法的返回值 !
继续改进:
1 from collections import Iterable,Iterator 2 import time 3 4 class ClassMate: 5 def __init__(self): 6 self.names = list() 7 8 def add(self,name): 9 self.names.append(name) 10 11 def __iter__(self): 12 # pass #必须要返回一个具有 iter 和 next 方法的对象 13 return MyIterator(self.names) 14 15 16 class MyIterator: 17 def __init__(self,args): 18 self.args = args 19 self.current_num = 0 20 def __iter__(self): 21 pass 22 def __next__(self): 23 if self.current_num<len(self.args): 24 ret = self.args[self.current_num] 25 self.current_num +=1 26 return ret 27 else: 28 raise StopIteration #结束for 循环 29 30 if __name__ == ‘__main__‘: 31 classmate = ClassMate() 32 classmate.add("tom") 33 classmate.add("jane") 34 classmate.add("egon") 35 36 for name in classmate: 37 print(name) 38 time.sleep(1)
不过这时的问题是:有个多余的类,所以我们考虑在一个类里就搞定事情:
最终如下:
from collections import Iterable,Iterator import time class ClassMate: def __init__(self): self.names = list() self.current_num = 0 def add(self,name): self.names.append(name) def __iter__(self): # pass #必须要返回一个具有 iter 和 next 方法的对象 return self #返回的是个具有 next 和iter 的迭代器 def __next__(self): if self.current_num<len(self.names): ret = self.names[self.current_num] self.current_num +=1 return ret #它就是for 循环的name else: raise StopIteration #for in 结构会默认处理这个异常 if __name__ == ‘__main__‘: classmate = ClassMate() classmate.add("tom") classmate.add("jane") classmate.add("egon") for name in classmate: time.sleep(1) print(name) ‘‘‘ 这也说明了一点: 一个可以迭代的对象 不一定 是个迭代器 一个迭代器 一定 是可迭代的对象 ‘‘‘
迭代器的应用:
pass
生成器:
协程-yield:
协程-greenlet:
协程-gevent:
进程,线程,协程区别:
案例:并发下载器:
这上面的是迭代器,生成器,以后还会说装饰器,先看一个装饰器的小例子:
import time def decorator(func): def wrapper(name): t1=time.perf_counter() func(name) time.sleep(1) print("总时间为:",time.perf_counter() - t1) return wrapper @decorator def test(name): print("Hello World!",name) if __name__ == ‘__main__‘: test("tom")
它们三个(迭代器,生成器和装饰器)是Python 高级语法中重要的内容!
---恢复内容结束---
迭代器:
生成器:
协程-yield:
协程-greenlet:
协程-gevent:
进程,线程,协程区别:
案例:并发下载器:
这上面的是迭代器,生成器,以后还会说装饰器,先看一个装饰器的小例子:
import time def decorator(func): def wrapper(name): t1=time.perf_counter() func(name) time.sleep(1) print("总时间为:",time.perf_counter() - t1) return wrapper @decorator def test(name): print("Hello World!",name) if __name__ == ‘__main__‘: test("tom")
它们三个(迭代器,生成器和装饰器)是Python 高级语法中重要的内容!
以上是关于多线程--协程的主要内容,如果未能解决你的问题,请参考以下文章