what' the python之字元編碼與檔案處理,
用文字編輯器開啟一個檔案就是把一個檔案讀入了記憶體中 ,所以開啟檔案的操作也是在記憶體中的,斷電即消失,所以若要儲存其內容就必須點擊儲存讓其存入硬碟中
python解譯器執行py檔案的原理 :
第一階段:python解譯器啟動,此時就相當於啟動了一個文字編輯器
第二階段:python解譯器相當於文字編輯器,去開啟test.py檔案,從硬碟上將test.py的檔案內容讀入到記憶體中(小複習:pyhon的解釋性,決定瞭解釋器只關心檔案內容,不關心檔案尾碼名)
第三階段:python解譯器解釋執行剛剛載入到記憶體中test.py的代碼( ps:在該階段,即執行時,才會識別python的文法,執行檔案內代碼,執行到name="jack",會開闢記憶體空間存放字串"jack")
總結:python解譯器於檔案本編輯的異同
相同點:python解譯器是解釋執行檔案內容的,因而python解譯器具備讀py檔案的功能,這一點與文字編輯器一樣
不同點:文字編輯器將檔案內容讀入記憶體後,是為了顯示/編輯,而python解譯器將檔案內容讀入記憶體後,是為了執行(執行前會識別python文法)
what's the 字元編碼?
字元編碼:將人輸入的字元轉換成電腦能識別的位元字的過程的定義的標準就叫字元編碼。
字元=====(字元編碼)====>位元
由於電腦起源於美國,所以一開始設定的字元編碼只針對英文。最早的字元編碼叫ASCII碼,後來為了滿足更多國家的文字的需求,又定製了其他的字元編碼。如中國的是GBK,日本的是shift_JIS,韓國是Euc_kr等等。
ASCII碼:一個Bytes代表一個字元(英文字元/鍵盤上的所有其他字元),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字元。(ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字元了(英文字元/鍵盤的所有其他字元)後來為了將拉丁文也編碼進了ASCII表,將最高位也佔用了)
GBK:2Bytes代表一個字元(一個中文)
因為每個國家有他們自己的標準,若同時使用多種語言時,標準不同會造成亂碼,這就需要設定一個通用的萬國標準,這就是Unicode和UTF-8
unicode:統一用2Bytes代表一個字元;優點是字元->數位轉換速度快,缺點是佔用空間大,因為英文只需1Bytes,而他統一使用2Bytes,就會造成資源浪費及佔用空間大
UTF-8:對英文字元只用1Bytes表示,對中文字元用3Bytes;優點是節省空間的,缺點是:字元->數位轉換速度慢,因為每次都需要計算出字元需要多長的Bytes才能夠準確表示
註:儲存時,python2預設ASCII碼,python3預設UTF-8,可在檔案開頭輸入#-*-coding:utf-8-*-,來指定解譯器用什麼字元編碼
規定:
註解:所有程式,最終都要載入到記憶體,程式儲存到硬碟中不同的國家使用的是不同的編碼格式,但是到記憶體中我們必須相容萬國(電腦可以運行任何國家的程式原因在於此),所以統一且固定使用unicode。你可能會說相容萬國utf-8也可以,確實可以,完全可以正常工作,之所以不用是因為unicode比utf-8更高效(uicode固定用2個位元組編碼,utf-8則需要計算),但是unicode更浪費空間,沒錯,這就是用空間換時間的一種做法。而存放到硬碟,或者網路傳輸,都需要把unicode轉成utf-8,因為資料的傳輸,追求的是穩定,高效,資料量越小資料轉送就越靠譜,於是都轉成utf-8格式的,而不是unicode。
重點!:檔案在記憶體中使用的是Unicode,若要儲存到硬碟中就要經過encode存為UTF-8,硬碟中的檔案是以UTF-8的形式儲存的,若要調用就必須經過decode成Unicode載入到記憶體中
註:在檔案編輯器的右下角可以選擇字元編碼,一般情況下預設為UTF-8
亂碼的產生有兩種情況:
一、一份檔案包含有各國語言,若儲存時用的是某個國家的標準而不是萬國標準的話,其他非本國的語言的文字就會以亂碼的形式被儲存,以後再調用時一直為亂碼,等於檔案被損壞,亂碼無法複原。
二、一份檔案以自己國家的標準的形式儲存,在調用時用了其他的標準時,因為無法載入就會產生亂碼,此時的亂碼通過變為原來的標準就可以恢複
結論:要避免亂碼的產生,最好的方法就是以什麼字元編碼儲存就以什麼字元編碼開啟
瀏覽網頁的時候,伺服器會把動態產生的Unicode內容轉換為UTF-8再傳輸到瀏覽器
如果服務端encode的編碼格式是utf-8, 用戶端記憶體中收到的也是utf-8編碼的二進位。
what's the 檔案處理
檔案處理的流程為:
檔案開啟模式:檔案控制代碼 = open('檔案路徑', '模式')
註:開啟檔案時,需要指定檔案路徑和以何等方式開啟檔案,開啟後,即可擷取該檔案控制代碼,日後通過此檔案控制代碼對該檔案操作。
open:
1 會向作業系統發起系統調用,操作會開啟一個檔案
2 在python程式中會產生一個值指向作業系統開啟的那個檔案,我們可以把該值賦值一個變數
回收資源:f.close() 一定要做,關閉作業系統開啟的檔案,即回收作業系統的資源
開啟檔案的模式有:
- r ,唯讀模式【預設模式,檔案必須存在,不存在則拋出異常】
- w,唯寫模式【不可讀;不存在則建立;存在則清空內容】
- x, 唯寫模式【不可讀;不存在則建立,存在則報錯】
- a, 追加模式【可讀; 不存在則建立;存在則只追加內容】
"+" 表示可以同時讀寫某個檔案
- r+, 讀寫【可讀,可寫】
- w+,寫讀【可讀,可寫】
- x+ ,寫讀【可讀,可寫】
- a+, 寫讀【可讀,可寫】
"b"表示以位元組的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
註:以b方式開啟時,讀取到的內容是位元組類型,寫入時也需要提供位元組類型,不能指定編碼
flush原理:
1、檔案操作是通過軟體將檔案從硬碟讀到記憶體
2、寫入檔案的操作也都是存入記憶體緩衝區buffer(記憶體速度快於硬碟,如果寫入檔案的資料都從記憶體刷到硬碟,記憶體與硬碟的速度延遲會被無限放大,效率變低,所以要刷到硬碟的資料我們統一往記憶體的一小塊空間即buffer中放,一段時間後作業系統會將buffer中資料一次性刷到硬碟)
3、flush即強制將寫入的資料刷到硬碟
讀取的進度條,或者叫捲軸的代碼:
import timefor i in range(10): print('#',end='',flush=True) time.sleep(0.2)else: print()
檔案內游標的移動:
一: read(3):
1. 檔案開啟檔案為文字模式時,代表讀取3個字元
2. 檔案開啟檔案為b模式時,代表讀取3個位元組
二: 其餘的檔案內游標移動都是以位元組為單位如seek,tell,truncate
注意:
1. seek有三種移動方式0,1,2,其中1和2必須在b模式下進行,但無論哪種模式,都是以bytes為單位移動的
2. truncate是截斷檔案,所以檔案的開啟檔案必須可寫,但是不能用w或w+等方式開啟,因為那樣直接清空檔案了,所以truncate要在r+或a或a+等模式下測試效果
上下文管理(即建立一個新檔案,在源檔案中讀一行就在新檔案中寫一行)
with open('a.txt','r') as read_f,open('b.txt','w') as write_f: data=read_f.read() write_f.write(data)
迴圈讀取每一行的內容:
with open('a.txt','r',encoding='utf-8') as f: while True: line=f.readline()#只適用於小檔案 if not line:break print(line,end='')
檔案的修改:
import oswith open('a.txt','r',encoding='utf-8') as read_f,\ open('a.txt.swap','w',encoding='utf-8') as write_f: for line in read_f: write_f.write(line.replace('alex_BSB','BB_alex_SB'))os.remove('a.txt')os.rename('a.txt.swap','a.txt')