在開始介紹協程之前,咱們先了解一下迭代器和生成器,因為要學習協程,這兩部分更是關鍵。
迭代:是訪問集合元素的一種方法,迭代器是乙個可以記住遍歷的位置的物件。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束,迭代器只能往前不能後退。
我們可以對list,tuple,str等型別的資料使用for…in…的迴圈語法從其中依次拿到資料進行使用,我們把這樣的過程稱為遍歷,也叫迭代。
如何判斷是否可以迭代:
from collections import iterable
isinstance(資料,iterable)
如果返回值為true,則表示可以迭代。
迭代器:儲存的是生成資料的方式,而不是已經生成的資料。
for temp in ***_obj:
pass
1. 判斷***_obj是否可以迭代
2. 在第1步成立的前提下,呼叫iter函式,得到***_obj物件的__iter__方法的返回值
3. __iter__方法的返回值 是乙個迭代器
判斷物件iterator是否是迭代器:
from collections import iterator
iterator = iter(函式名)
isinstance(iterator,iterator)
如果返回值為true,則表示物件是迭代器。
迭代器的優點:能夠實現for迴圈,能夠取裡面的資料,裡面儲存的是生成資料的方式。而且不會占用太多的記憶體。
就好比python2中的range和xrange,range返回的是資料本身,xrange返回的是乙個可迭代物件,python3中range也可以當成xrange用。
生成器:是一種特殊的迭代器。
建立生成器的方法:
1. nums = (x*2 for x in range(20)) # 返回的是乙個可迭代物件,裡面是生成資料的方法,節省空間,就是將列表的中括號變成小括號,可用for迴圈
2. 在函式中使用yield,那麼這個函式則認為不再是函式,而是乙個生成器模板,這是呼叫這個函式建立物件的時候,不再是呼叫函式,而是建立乙個生成器物件。
製作乙個簡單的生成器案例:
def create_num(all_num):
a, b = 0, 1
current_num = 0
while current_num < all_num:
# print(a)
yield a # 如果乙個函式中有yield語句,那麼這個就是在是函式,而是乙個生成器模板
a, b = b, a+b
current_num += 1 # 如果在呼叫create_num的時候,發現這個函式中有yield,那麼此時,不是呼叫函式,而是建立乙個生成器物件
obj = create_num(10)
obj2 = create_num(20)
以上就是迭代器和生成器的大致內容,而在以後的python程式設計中,使用最多的卻是協程:gevent。
首先我們需要在電腦上安裝gevent
$ pip3 install 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()
這個就是gevent的簡單使用,通過執行結果可以知道,它是乙個單執行緒,而這個也是協程的一大優點,因為它既是乙個單執行緒,但也可以實現多工,它在資源排程的過程中,利用了其他協程中延時的空隙去執行其他的協程。
gevent實現多工:
import gevent
def f(n):
for i in range(n):
print(gevent.getcurrent(),i)
gevent.sleep(0.5)
g1 = gevent.spawn(f,5)
g2 = gevent.spawn(f,5)
g3 = gevent.spawn(f,5)
g1.join()
g2.join()
g3.join()
因為gevent是乙個封裝好了的模組,裡面有自己的延時命令,如果以後碰到了其他的延時命令,比如:
time.sleep(0.5)
這時候,這個延時命令並沒有執行,需要給這段程式加個補丁:
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()
monkey.patch_all()這句**會將裡面的time.sleep()自動轉化為gevent.sleep()命令,從而實現延時。
如果在開發過程中,需要執行的協程數量過大,我們可以通過更加簡便的**進行:
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)
g = [g1,g2,g3]
g1 = gevent.spawn(f,5)
g2 = gevent.spawn(f,5)
g3 = gevent.spawn(f,5)
gevent.joinall(g)
這就是協程在開發過程中最後的模板。 python 多工程式設計
多工 在同一時間內執行多個任務 多工的目的 多工的最大好處是充分利用cpu資源,提高程式的執行效率 併發 在一段時間內交替執行多個任務 並行 在同一時刻同時執行多個任務 程序 執行中的程式,分配資源的最小單位 執行緒 使用資源的最小單位 程序和執行緒的關係 乙個程式執行後至少有乙個程序,每個程序預設...
Python 多工網路程式設計
提高效能的多工程式設計 可以用單執行緒 單程序 非堵塞併發的方法來實現多工,socket.setblocking false 將套接字變為非堵塞,會讓accept在沒有客戶端到來之前和socket.recv 沒有收到資料的時候從堵塞變為異常,從而我們可以讓它丟擲異常,繼續執行下面的 我們可以新建乙個...
python 多工程式設計 程序
程序 想要實現多工可以使用程序來完成,概念 乙個正在執行的程式或者軟體就是乙個程序,它是作業系統進行資源發呢排的基本單位 乙個程式執行後至少有乙個程序,乙個程序預設有乙個執行緒,程序裡面可以建立多個執行緒,執行緒依附在程序裡面的,沒有程序就沒有執行緒。程序的使用 1 匯入程序包 import mul...