10. 字元編碼與檔案操作
一、 字元編碼
1. 介紹
概念:字元編碼主要的研究物件是文字檔案(圖片、視訊、音訊除外)
文字編輯器讀取檔案內容的流程:
1.啟動一個文字編輯器
2.文字編輯器將檔案內容從硬碟讀入記憶體
3.文字編輯器將剛剛讀入記憶體中的內容顯示到螢幕上
python直譯器執行檔案的流程:
1.啟動python直譯器,此時就相當於啟動了一個文字編輯器
2.python直譯器相當於文字編輯器,將硬碟上的py檔案的內容讀入到記憶體中
3.python直譯器執行剛剛讀入到記憶體的內容,開始識別python語法
2. 字元編碼的發展史
第一階段(一家獨大):
計算機是由美國人發明的,為了讓計算機能識別英文,定義了一個數字與英文字元的對應關係-----字元編碼表(ASCII碼錶)
ASCII碼:只記錄了英文字元與數字的對應關係
1Byte對應1個英文字元
A-Z 65-90
a-z 97-122
第二階段(群雄割據):
中國:
GBK碼(國標) 記錄中文、英文字元與數字的對應關係
1Byte儲存英文字元
2Byte儲存中文字元,如果不夠用則使用 3Byte或 4Byte(2Byte最多能對應的中文字元數量為2**16=65536個)
韓國:
Euc_kr編碼表:記錄韓文、英文字元與數字的對應關係
日本:
shift_JIS:記錄日文、英文字元與數字的對應關係
第三階段(天下一統):
unicode(萬國碼):
記錄了所有國家的字元與數字的對應關係、所有的字元最少採用2Byte儲存
現在的計算機可以輸出所有國家的字元,記憶體使用的是unicode編碼
由於unicode最少採用2Byte,而ASCII碼中1Byte對應1個英文字元,因此unicode會浪費儲存空間和IO時間,所以又開發了一個編碼(utf-8)
utf-8:
1Byte儲存英文字元
3Byte儲存中文字元
結論:
記憶體中的編碼不需要考慮,只考慮硬碟上的即可
英文、漢字-------unicode----------GBK
英文、日文-------unicode----------shift-JIS
萬國字元----------unicode----------utf-8
3. 字元編碼實際應用
3.1 編碼與解碼
編碼(encode):將人類能夠讀懂的字元轉換成計算機能夠直接讀懂的字元
解碼(decode):將計算機能夠直接讀懂的字元轉換成人類能夠讀懂的字元
編碼示例:將字串按gbk進行編碼
字串前如果加了字母b,表示該資料型別為Byte型別,Byte型別可以看成是二進位制
解碼示例:將存成gbk的字串依然按照gbk格式進行解碼
3.2如何解決亂碼問題
資料當初以什麼格式進行編碼就以什麼格式進行解碼
s2 = '阿根廷梅西'
# 以gbk格式進行編碼
a = s2.encode('gbk')
# 列印編碼後的資料
print(a) # b'\xb0\xa2\xb8\xf9\xcd\xa2\xc3\xb7\xce\xf7'
# 以Euc_kr格式進行解碼
print(a.decode('euc_kr')) # 각몽溪첨鮫
# 以gbk格式進行解碼
print(a.decode('gbk')) # 阿根廷梅西
3.3 python直譯器如何解決亂碼問題
python2直譯器:預設的編碼是ASCII碼(計算機是由美國人發明的)
1.檔案頭:必須寫在檔案的最上方,告訴直譯器使用指定的編碼
# coding:utf8
# -*- coding:utf8 -*- (這是一種美化寫法)
在python2直譯器中沒有指定編碼格式時,如果寫了中文註釋,執行程式碼也會報錯(python2預設ASCII)
按照gbk或者utf-8進行編碼就不會報錯
2.字元字首:在使用python2直譯器的環境下定義字串習慣在前面加u
(u即unicode,記憶體中格式為unicode,硬碟中格式為utf-8)
不指定檔案頭為utf-8給字串字首加u時,還是會按照ASCII進行編碼,仍然會報錯
python3直譯器 :預設使用utf-8編碼
二、 檔案操作
1. 概念與語法
# 1.1什麼是檔案
作業系統提供給使用者可以直接操作硬碟的快捷方式
# 1.2操作檔案的流程
開啟檔案、建立檔案
編輯內容
儲存內容
關閉檔案
# 1.3基本語法
結構1(瞭解):
f1 = open( ) 開啟檔案
a = f1.read( ) 讀取檔案
f1.close( ) 關閉檔案
結構2(推薦使用):
with open( ) as f:
pass
# 1.4使用關鍵字開啟檔案
為了防止特殊符號轉義,直接加r
open(r'測試.txt') # 相對路徑
open(r'D:\Project\learn\測試.txt') # 絕對路徑
開啟檔案
a = open(r'D:\Project\learn\測試.txt')
print(a)
# <_io.TextIOWrapper name='D:\\Project\\learn\\測試.txt' mode='r' encoding='cp936'>
open(檔案的路徑,檔案的操作模式,檔案的編碼)
1.檔案的路徑是必須要寫的
2.檔案的操作模式、檔案的編碼有時候不用寫
如語法中所述,open完最後都需要執行close,而close程式碼容易被遺忘,進而引出了with方法
# 1.5with上下文管理
with會自動呼叫close關閉檔案
2. 檔案的讀寫模式
r read 只讀模式:只能讀不能寫
w write 只寫模式:只能寫不能讀
a append 只追加模式:在檔案末尾新增內容
r模式
路徑不存在:直接報錯
路徑存在:正常開啟檔案並等待內容讀取
w模式
路徑不存在:自動建立檔案
路徑存在:先清空檔案內容,再寫入資料
(最早的時候換行方式\r\n,\r的作用是游標從第一行末尾移動到第二行末尾,\n的作用是游標從行尾到行首,現在一個字元也可以換行)
a模式
路徑不存在:自動建立檔案
路徑存在:不會清空檔案內容,而是在檔案末尾等待新內容的新增
a模式也不可讀
3. 檔案的操作模式
t模式
即文字模式 ,是預設的模式
r rt
w wt
a at
1.該模式只能操作文字檔案
2.該模式讀寫都是以字串為單位(即都是以Unicode為單位).
3.該模式必須指定encoding引數,encoding:utf-8(即Unicode轉換成utf-8存入硬碟,或者將utf-8轉換成unicode讀入記憶體)
b模式
二進位制模式 可以操作任意型別的檔案
r rb b不可省略
w wb b不可省略
a ab b不可省略
1.該模式可以操作任意型別的檔案
2.該模式一定不能指定encoding引數
3.該模式讀寫都是以Byte型別(二進位制)為最小單位
4. 檔案的內建方法
read() 一次性讀取檔案內容
1.執行完之後游標在檔案末尾,繼續讀取沒有內容
2.當檔案內容特別大的時候,容易造成記憶體溢位
readline() 一次只讀一行內容
readlines() 結果是一個列表,裡面的各個元素是檔案的一行行內容
# readable() # 判斷當前檔案是否可讀
# writable() # 判斷檔案是否可寫
# 支援for迴圈,一行行讀取檔案內容,記憶體中同一時刻只會有一行內容
write() 寫入檔案內容(字串或者bytes型別)
writelines() 可以將列表中多個元素寫入檔案
with open(r'D:\Project\learn\測試.txt', 'wt', encoding='utf-8') as f7:
f7.writelines(['阿根廷\n', '足球\n', '巨星\n', '梅西'])
flush() # 相當於主動按了ctrl+s(儲存)