非同步程式設計(簡稱非同步)是許多現代語言的功能,它使程式可以處理多個操作,而無需等待或結束通話其中的任何乙個。 這是一種有效處理網路或檔案i / o等任務的明智方法,其中程式的大部分時間都花在等待任務完成上。
考慮乙個開啟100個網路連線的web抓取應用程式。 您可以開啟乙個連線,等待結果,然後開啟下乙個連線並等待結果,依此類推。 程式執行的大部分時間都花在等待網路響應上,而不是在做實際的工作。
[ 同樣在infoworld上:每個python開發人員都有24個python庫
] 非同步語法現在已成為python的標準功能,但是習慣於一次做一件事的長期pythonista使用者可能難以解決。 在本文中,我們將**非同步程式設計在python中的工作方式以及如何使用它。
請注意,如果要在python中使用非同步,最好使用python 3.7或python 3.8(撰寫本文時的最新版本)。 我們將使用這些語言版本中定義的python非同步語法和輔助函式。
通常,使用非同步的最佳時機是當您嘗試執行具有以下特徵的工作時:
非同步使您可以並行設定多個任務並有效地遍歷它們,而不會阻塞應用程式的其餘部分。
可以很好地與非同步工作的一些任務示例:
重要的是要注意,非同步程式設計不同於多執行緒或多處理。 非同步操作都在同乙個執行緒中執行,但是它們可以根據需要相互轉化,這使得非同步處理比執行緒或多處理多種任務的效率更高。 (有關此內容,請參見下文。)
[ 同樣在infoworld上:python 3.8中最好的新功能
] python最近新增了兩個關鍵字async
和await
,用於建立非同步操作。 考慮以下指令碼:
def get_server_status(server_addr)
# a potentially long-running operation ...
return server_status
def server_ops()
results =
return results
相同指令碼的非同步版本(不起作用,僅足以使我們了解語法的工作原理)可能看起來像這樣。
async def get_server_status(server_addr)
# a potentially long-running operation ...
return server_status
async def server_ops()
results =
return results
以async
關鍵字為字首的函式成為非同步函式,也稱為coroutines 。 協程的行為與常規函式不同:
所以,如果我們不能稱之為async
非非同步函式的功能,我們不能執行的async
功能直接,我們如何使用它們? 答:通過使用asyncio
庫,它將async
與python的其餘部分聯絡起來。
[ 同樣在infoworld上:每種程式設計需要12個python
]
import asyncio
from web_scraping_library import read_from_site_async
async def main(url_list):
return await asyncio.gather(*[read_from_site_async(_) for _ in url_list])
urls = ['','','']
results = asyncio.run(main(urls))
print (results)
在上面的示例中,我們使用兩個常見的asyncio
函式:
這裡的想法是,我們立即開始對所有站點的讀取操作,然後在它們到達時收集結果(因此asyncio.gather()
)。 在進行下乙個操作之前,我們不等待任何乙個操作完成。
[ 同樣在infoworld上:python virtualenv和venv做和不做
] 我們已經提到了python非同步應用程式如何使用協程作為主要成分,並利用asyncio
庫執行它們。 其他一些要素也是python非同步應用程式的關鍵:
asyncio
庫建立和管理事件迴圈 ,即執行協程直到完成的機制。 在python程序中,一次只能執行乙個事件迴圈,如果這樣做只是為了使程式設計師更容易跟蹤其中的內容。
將協程提交到事件迴圈以進行處理時,可以獲取task
物件,該物件提供了一種從事件迴圈外部控制協程行為的方法。 例如,如果需要取消正在執行的任務,可以通過呼叫任務的.cancel()
方法來完成。
import asyncio
from web_scraping_library import read_from_site_async
tasks =
async def main(url_list):
for n in url_list:
print (tasks)
return await asyncio.gather(*tasks)
urls = ['','','']
loop = asyncio.get_event_loop()
results = loop.run_until_complete(main(urls))
print (results)
該指令碼更明確地使用事件迴圈和任務物件。
您需要對事件迴圈及其事件進行多少控制,將取決於您所構建的應用程式的複雜程度。 如果您只想提交一組固定的作業以同時執行(與我們的web抓取工具一樣),則不需要太多控制權-僅足以啟動作業和收集結果。
相比之下,如果您要建立乙個完善的web框架,則需要對協程和事件迴圈的行為進行更多的控制。 例如,在應用程式崩潰的情況下,您可能需要優雅地關閉事件迴圈 ,或者,如果從另乙個執行緒呼叫事件迴圈, 則以執行緒安全的方式執行任務 。
[ 也在infoworld上:anaconda入門,anaconda是資料科學的python發行版
] 在這一點上,您可能想知道,為什麼使用非同步而不是執行緒或多處理,而這在python中早已可用?
首先,非同步與執行緒或多處理之間存在乙個關鍵區別,即使這些內容是如何在python中實現的也是如此。 非同步與併發有關,而執行緒和多處理則與並行有關。 併發涉及一次將效率有效地分配給多個任務,例如,在雜貨店等待註冊時檢查電子郵件。 並行涉及多個**併排處理多個任務,例如,在雜貨店開啟五個單獨的暫存器。
大多數情況下,非同步是執行緒的良好替代品, 因為執行緒是在python中實現的 。 這是因為python不使用os執行緒,而是使用其自己的協作執行緒,在直譯器中一次僅執行乙個執行緒。 與協作執行緒相比,非同步提供了一些關鍵優勢:
另一方面,python中的多處理最適合cpu密集而不是i / o密集的作業。 非同步實際上與多處理並駕齊驅,因為您可以使用asyncio.run_in_executor()
將cpu密集型作業從**程序委派給程序池,而不會阻塞該**程序。
] 最好的第一件事是構建自己的一些簡單非同步應用程式。 現在有很多很好的例子 ,python中的非同步程式設計已經經歷了幾個版本,並且需要幾年的時間才能發展起來並得到更廣泛的使用。 即使您不打算使用其所有功能,asyncio
的官方文件也值得閱讀以了解其功能。
您可能還會探索越來越多的非同步驅動的庫和中介軟體,其中許多提供了資料庫聯結器,網路協議等的非同步,非阻塞版本。aio-libs
儲存庫具有一些關鍵的儲存庫 ,例如用於web訪問的aiohittp
庫。 也值得在python軟體包索引中搜尋帶有async
關鍵字的庫。 對於非同步程式設計之類的東西,最好的學習方法是看別人如何使用它。
from:
教程 從零開始 使用Python進行深度學習!
現在的人工智慧已經呈指數級增長。比如,自動駕駛汽車的時速達數百萬英里,ibm watson在診斷病人的情況上比醫生更好,alphago擊敗了世界冠軍。這其中,人工智慧扮演著關鍵的角色。隨著人工智慧的進一步發展,人們也提出了更高的要求。希望它們可以解決更加複雜的問題。而解決問題的核心就是深度學習。te...
開始使用Unix
本人使用的macbook pro md101,通過mac的終端登入到unix系統。登入unix系統 首先在終端中輸入login,然後終端會顯示login 然後輸入使用者標識,按return後,會顯示password 輸入密碼即可登入,隨後會顯示上次登入的時間以及使用的終端,無論何時,你都要花時間檢查...
開始使用Gulp
結語參考與擴充套件 接觸gulp不多,感觸卻多。不過一句話 省了好多麻煩。如果你也是做web前端的,並且也想更加便捷高效的去完成自己的專案,那麼可以嘗試使用一下gulp。首先看看gulp的定義 gulp是乙個基於流的自動化構建工具。大家都明白什麼是自動化 就是懶人不用動手了唄 構建工具就是說這是乙個...