python中的io編程(python ion)

本文目錄一覽:

python語言基礎知識是什麼?

如下:

一、Python語言基礎

Python核心:Python數據基本運算、語句、容器、函數

Python 面向對象編程:OOA、OOD、OOP、天龍八部技能系統框架 設計 Python高級:模塊、包、函數式編程、文件。

二、Python高級軟體開發技術

Linux操作系統 :Linux常用命令、編輯工具、vim/Pycharm

數據結構與演算法 :鏈表、棧和隊列、樹和二叉樹、查找排序

IO網路編程:文件操作、位元組流讀寫、網路協議、套接 字、TCP/UDP

並發編程:多進程、進程池、進程通信、多線程、線程鎖、多任務並發、IO模型、協程

Python 正則表達式:正則表達式、貪婪模和非貪婪模式、re模塊

MySQL基礎:資料庫應用、SQL語言、Mysql增刪改查、 pymysql模塊

三、Python Web全棧式工程師

HTML/CSS HTML5標籤,CSS選擇器,CSS樣式屬性以 及值

Java :JS流程式控制制,DOM,BOM,JQuery API

MySQL高級:MySQL索引、事務、引擎、優化、pymysql 模塊使用

Python Django 框架:Django、模板、視圖、模型、請求對象等

 Ajax Ajax,:JSON, Jquery對Ajax的支持, 跨域訪問

四、Python 爬蟲

Redis:Redis、string、hash、list、set、zset、 Python與MySQL和Redis結合

爬蟲、HTTP、BeautifulSoup,XPath,Scrapy其實無論是學習什麼知識,都要有一個對學習目標的清楚認識。 只有這樣才能朝著目標持續前進,少走彎路,從學習中得到不斷的提升,享受python學習計劃的過程。

Python用asyncio模塊做協程非同步IO爬蟲功能,為啥我這兩個模塊下的代碼錯誤這麼多!

隨著node.js的盛行,相信大家今年多多少少都聽到了非同步編程這個概念。Python社區雖然對於非同步編程的支持相比其他語言稍顯遲緩,但是也在Python3.4中加入了asyncio,在Python3.5上又提供了async/await語法層面的支持,剛正式發布的Python3.6中asynico也已經由臨時版改為了穩定版。下面我們就基於Python3.4+來了解一下非同步編程的概念以及asyncio的用法。

什麼是協程

通常在Python中我們進行並發編程一般都是使用多線程或者多進程來實現的,對於計算型任務由於GIL的存在我們通常使用多進程來實現,而對與IO型任務我們可以通過線程調度來讓線程在執行IO任務時讓出GIL,從而實現表面上的並發。

其實對於IO型任務我們還有一種選擇就是協程,協程是運行在單線程當中的「並發」,協程相比多線程一大優勢就是省去了多線程之間的切換開銷,獲得了更大的運行效率。Python中的asyncio也是基於協程來進行實現的。在進入asyncio之前我們先來了解一下Python中怎麼通過生成器進行協程來實現並發。

example1

我們先來看一個簡單的例子來了解一下什麼是協程(coroutine),對生成器不了解的朋友建議先看一下Stackoverflow上面的這篇高票回答。

python的io模塊和os模塊有什麼區別

os: This module provides a portable way of using operating system dependent functionality.

這個模塊提供了一種方便的使用操作系統函數的方法。

os 常用方法

os.remove() 刪除文件

os.rename() 重命名文件

os.walk() 生成目錄樹下的所有文件名

os.chdir() 改變目錄

os.mkdir/makedirs 創建目錄/多層目錄

os.rmdir/removedirs 刪除目錄/多層目錄

os.listdir() 列出指定目錄的文件

os.getcwd() 取得當前工作目錄

os.chmod() 改變目錄許可權

os.path.basename() 去掉目錄路徑,返迴文件名

os.path.dirname() 去掉文件名,返回目錄路徑

os.path.join() 將分離的各部分組合成一個路徑名

os.path.split() 返回( dirname(), basename())元組

os.path.splitext() 返回 (filename, extension) 元組

os.path.getatime\ctime\mtime 分別返回最近訪問、創建、修改時間

os.path.getsize() 返迴文件大小

os.path.exists() 是否存在

os.path.isabs() 是否為絕對路徑

os.path.isdir() 是否為目錄

os.path.isfile() 是否為文件

Python中的io模塊是用來處理各種類型的I/O操作流,主要是文件處理。主要有三種類型的I/O類型:文本I/O(Text I/O),二進位I/O(Binary I/O)和原始I/O(Raw I/O)。它們都是通用類別,每一種都有不同的後備存儲。屬於這些類別中的任何一個的具體對象稱為文件對象,其他常用的術語為流或者類文件對象。

Python非同步編程全攻略

如果你厭倦了多線程,不妨試試python的非同步編程,再引入async, await關鍵字之後語法變得更加簡潔和直觀,又經過幾年的生態發展,現在是一個很不錯的並發模型。

下面介紹一下python非同步編程的方方面面。

因為GIL的存在,所以Python的多線程在CPU密集的任務下顯得無力,但是對於IO密集的任務,多線程還是足以發揮多線程的優勢的,而非同步也是為了應對IO密集的任務,所以兩者是一個可以相互替代的方案,因為設計的不同,理論上非同步要比多線程快,因為非同步的花銷更少, 因為不需要額外系統申請額外的內存,而線程的創建跟系統有關,需要分配一定量的內存,一般是幾兆,比如linux默認是8MB。

雖然非同步很好,比如可以使用更少的內存,比如更好地控制並發(也許你並不這麼認為:))。但是由於async/await 語法的存在導致與之前的語法有些割裂,所以需要適配,需要付出額外的努力,再者就是生態遠遠沒有同步編程強大,比如很多庫還不支持非同步,所以你需要一些額外的適配。

為了不給其他網站帶來困擾,這裡首先在自己電腦啟動web服務用於測試,代碼很簡單。

本文所有依賴如下:

所有依賴可通過代碼倉庫的requirements.txt一次性安裝。

首先看一個錯誤的例子

輸出如下:

發現花費了3秒,不符合預期呀。。。。這是因為雖然用了協程,但是每個協程是串列的運行,也就是說後一個等前一個完成之後才開始,那麼這樣的非同步代碼並沒有並發,所以我們需要讓這些協程並行起來

為了讓代碼變動的不是太多,所以這裡用了一個笨辦法來等待所有任務完成, 之所以在main函數中等待是為了不讓ClientSession關閉, 如果你移除了main函數中的等待代碼會發現報告異常 RuntimeError: Session is closed ,而代碼里的解決方案非常的不優雅,需要手動的等待,為了解決這個問題,我們再次改進代碼。

這裡解決的方式是通過 asyncio.wait 方法等待一個協程列表,默認是等待所有協程結束後返回,會返回一個完成(done)列表,以及一個待辦(pending)列表。

如果我們不想要協程對象而是結果,那麼我們可以使用 asyncio.gather

結果輸出如下:

通過 asyncio.ensure_future 我們就能創建一個協程,跟調用一個函數差別不大,為了等待所有任務完成之後退出,我們需要使用 asyncio.wait 等方法來等待,如果只想要協程輸出的結果,我們可以使用 asyncio.gather 來獲取結果。

雖然前面能夠隨心所欲的創建協程,但是就像多線程一樣,我們也需要處理協程之間的同步問題,為了保持語法及使用情況的一致,多線程中用到的同步功能,asyncio中基本也能找到, 並且用法基本一致,不一致的地方主要是需要用非同步的關鍵字,比如 async with/ await 等

通過鎖讓並發慢下來,讓協程一個一個的運行。

輸出如下:

通過觀察很容易發現,並發的速度因為鎖而慢下來了,因為每次只有一個協程能獲得鎖,所以並發變成了串列。

通過事件來通知特定的協程開始工作,假設有一個任務是根據http響應結果選擇是否激活。

輸出如下:

可以看到事件(Event)等待者都是在得到響應內容之後輸出,並且事件(Event)可以是多個協程同時等待。

上面的事件雖然很棒,能夠在不同的協程之間同步狀態,並且也能夠一次性同步所有的等待協程,但是還不夠精細化,比如想通知指定數量的等待協程,這個時候Event就無能為力了,所以同步原語中出現了Condition。

輸出如下:

可以看到,前面兩個等待的協程是在同一時刻完成,而不是全部等待完成。

通過創建協程的數量來控制並發並不是非常優雅的方式,所以可以通過信號量的方式來控制並發。

輸出如下:

可以發現,雖然同時創建了三個協程,但是同一時刻只有兩個協程工作,而另外一個協程需要等待一個協程讓出信號量才能運行。

無論是協程還是線程,任務之間的狀態同步還是很重要的,所以有了應對各種同步機制的同步原語,因為要保證一個資源同一個時刻只能一個任務訪問,所以引入了鎖,又因為需要一個任務等待另一個任務,或者多個任務等待某個任務,因此引入了事件(Event),但是為了更精細的控制通知的程度,所以又引入了條件(Condition), 通過條件可以控制一次通知多少的任務。

有時候的並發需求是通過一個變數控制並發任務的並發數而不是通過創建協程的數量來控制並發,所以引入了信號量(Semaphore),這樣就可以在創建的協程數遠遠大於並發數的情況下讓協程在指定的並發量情況下並發。

不得不承認非同步編程相比起同步編程的生態要小的很多,所以不可能完全非同步編程,因此需要一種方式兼容。

多線程是為了兼容同步得代碼。

多進程是為了利用CPU多核的能力。

輸出如下:

可以看到總耗時1秒,說明所有的線程跟進程是同時運行的。

下面是本人使用過的一些非同步庫,僅供參考

web框架

http客戶端

資料庫

ORM

雖然非同步庫發展得還算不錯,但是中肯的說並沒有覆蓋方方面面。

雖然我鼓勵大家嘗試非同步編程,但是本文的最後卻是讓大家謹慎的選擇開發環境,如果你覺得本文的並發,同步,兼容多線程,多進程不值得一提,那麼我十分推薦你嘗試以非同步編程的方式開始一個新的項目,如果你對其中一些還有疑問或者你確定了要使用的依賴庫並且大多數是沒有非同步庫替代的,那麼我還是建議你直接按照自己擅長的同步編程開始。

非同步編程雖然很不錯,不過,也許你並不需要。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/294000.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-26 13:15
下一篇 2024-12-26 13:15

相關推薦

  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智慧、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29

發表回復

登錄後才能評論