多线程--协程

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")
View Code

它们三个(迭代器,生成器和装饰器)是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")
View Code

它们三个(迭代器,生成器和装饰器)是Python 高级语法中重要的内容!

以上是关于多线程--协程的主要内容,如果未能解决你的问题,请参考以下文章

python 复习—并发编程实战——并发编程总结

利用协程多任务协程爬取前几页投诉网

利用协程多任务协程爬取前几页投诉网

简述python进程,线程和协程的区别及应用场景

unity3d网络通信用多线程会比协程好吗

Python并发编程——多线程与协程