1.什么是字符編碼?
人類在與計算機交互時,用的都是人類能讀懂的字符,如中文字符、英文字符、日文字符等,
而計算機只能識別二進制數,詳解如下。
二進制數即是由0和1組成的數字。計算機是基于點工作的,電的特性就是高低電頻,人類從邏輯層面
將高電頻對應為數字1,低電頻對應為數字0,這直接決定了計算機可以識別的是由0和1組成的數字。
毫無疑問,由人類的字符到計算機中的數字的,必須經歷的過程。
字符------------>翻譯------------->數字
翻譯的過程必須參照一個特定的標準,該標準稱之為字符編碼表,該表上存放的就是字符與數字一一
對應的關系。
字符編碼中的編碼指的是翻譯或者轉換的意思,即將人能理解的字符翻譯成計算機能識別的數字。
1.1字符編碼發展史
階段一:一家獨大
現代計算機起源于美國,所以最先考慮的僅僅是讓計算機識別英文字符,于是誕生了ASCII表
ASCII表的特點:
? ? 1、只有英文字符與數字一一對應
? ? 2、一個英文字符對應1Bytes,1Bytes=8bit,8bit最多包含256個數字,
? ? 可以對應256個字符,足夠表示所有的英文字符
階段二:群雄割據
為了讓計算機能夠識別中文和英文,中國人定制了GBK
GBK表的特點:
? ? 1、只有中文字符、英文字符與數字一一對應關系
? ? 2、一個英文字符對應1Bytes
一個中文字符對應2Bytes
補充說明:
? ? 1Bytes=8bit,8bit最多包含256個數字,可以對應256個字符,足夠表示所有英文字符
? ? 2Bytes=16bit,16bit最多包含65536個數字,可以對應65536個字符,足夠表示所有中文字符
每個國家都有各自的字符,為了讓計算機能夠識別自己國家的字符外加英文字符,各個國家制定了自己的
字符編碼表
Shift_JIS表的特點:
? ? 1、只有日文字符、英文字符與數字的一一對應關系
Euc-kr表的特點:
? ? 1、只有韓文字符、英文字符與數字的一一對應關系
此時,美國人用的計算機里使用字符編碼標準是ASCII、中國人用的計算機里使用字符編碼標準是GBK、
日本人用的計算機里使用字符編碼標準是Shift_JIS,此時的發展就比較混亂。
文件編輯存取文件的原理:
1.存文件文本
人類通過文本編輯器輸入的字符會被轉化成ASCII格式的二進制存放于內存中,如果需要永久保存,
則直接將ASCII格式的二進制寫入硬盤。
2.讀文本文件
直接將硬盤中的ASCII格式的二進制讀入內存。
此時無論是取還是存所用的字符編碼表都是一樣,那么肯定不會出現亂碼的情況。但是各個國家所用的字符編碼表不同,
那么如果在ASCII編碼格式的內存中直接輸入中文沒有GBK翻譯則出現亂碼,所有不匹配的語言都會出現亂碼,
所以我們必須制定一個兼容萬國字符的編碼表。
階段三:分久必合
unicode于1990年開始研發,1994年正式公布,具備兩大特點:
1.存在所有語言中的所有字符與數字的一一對應關系,即是兼容萬國字符
2.余傳統的字符編碼的二進制數都有關系。
很多地方或老的系統、應用軟件仍會采用各種各樣的傳統的編碼,這是歷史遺留問題。
軟件程序是存放在硬盤中的,要運行軟件,則需要將程序加載到內存中,面對硬盤各種傳統編碼
的軟件,想讓我們的計算機正常運行且不出現代碼,內存中必須要有一個兼容萬國的編碼,并且該
編碼需要與其他編碼有相對應的轉換關系(識別不同輸入字符加識別各種編碼的二進制數字,utf-8能識別不同字符,但是不能識別其他編碼數字)。
文本編輯器輸入任何字符首先是存在于內存中,是直接由unicode編碼的,存放于硬盤中,
則可以由其他任意編碼表轉換成二進制,只要該編碼可以支持相應的字符。
#英文字符可以被ASCII識別
英文字符--->unciode格式的數字--->ASCII格式的數字
#中文字符、英文字符可以被GBK識別
中文字符、英文字符--->unicode格式的數字--->gbk格式的數字
#日文字符、英文字符可以被shift-JIS識別
日文字符、英文字符--->unicode格式的數字--->shift-JIS格式的數字
解碼與編碼:
由字符轉換成內存中的unicode,以及由unicode轉換成其他編碼的過程,都成為編碼encode。
由內存中的unicode轉換成字符,以及由其他編碼轉換的成unicode的過程,都稱為解碼decode。
utf-8的由來
理論上是可以將內存中unicode格式的二進制直接存放于硬盤中的,
但由于unicode固定使用兩個字節來存儲一個字符,如果多國字符中包含大量的英文字符時,
使用unicode格式存放會額外占用一倍空間(英文字符其實只需要用一個字節存放即可),
然而空間占用并不是最致命的問題,最致命地是當我們由內存寫入硬盤時會額外耗費一倍的時間,
所以將內存中的unicode二進制寫入硬盤或者基于網絡傳輸時必須將其轉換成一種精簡的格式,
這種格式即utf-8
那為何在內存中不直接使用utf-8呢?
utf-8是針對Unicode的可變長度字符編碼:一個英文字符占1Bytes,一個中文字符占3Bytes,生僻字用更多的Bytes存儲
unicode更像是一個過渡版本,我們新開發的軟件或文件存入硬盤都采用utf-8格式,等過去幾十年,所有老編碼的文件都淘汰掉之后,
會出現一個令人開心的場景,即硬盤里放的都是utf-8格式,此時unicode便可以退出歷史舞臺,內存里也改用utf-8,天下重新歸于統一
英文字符------->unciode格式的數字-----ASCII編碼--->ASCII二進制
中文字符------->unciode格式的數字-----GBK編碼----->GBK二進制
萬國字符------->unciode格式的數字-----UFT-8------>UFT-8二進制
在存的時候unciode-----uft-8這條線可以存任何類型的字符,但是取時
uft-8的模式不能解碼其他編碼格式的二進制,所以會產生亂碼。所以在日常使用時,
讀取軟件需要看編碼是否一致。
2.字符編碼的應用
1、內存中固定unicode無論輸入任何字符都不會發生亂碼
2、我們能夠修改的是存取硬盤的編碼方式,如果編碼設置不正確將會出現亂碼。問題分兩種:
2.1存亂了:如果用戶輸入的內容包含中文日文,如果單純以shift_jis存,日文可以寫入,
而中文沒有找到對應關系則成為亂碼。而且此時已經存在硬盤中不可改了。
2.2讀亂了:如果硬盤中的數據是shift_jis格式存儲的,采用GBK格式讀入就亂了。
總結:
1.保證存的時候不亂:在由內存寫入硬盤時,必須將編碼格式設置為支持所輸入字符的編碼格式
2.保證讀的時候不亂:在由硬盤讀入內存時,必須采用寫入硬盤時相同的編碼格式
3.python解釋器執行文件的三個階段
執行py文件的前兩個階段就是python解釋器讀文本文件的過程,與文本編輯讀文本文件的前兩個階段沒人任何區別,
要保證讀不亂碼,則必須將python解釋器讀文件時采用的編碼方式設置為文件當初寫入硬盤時的編碼格式,
如果沒有設置,python解釋器則才用默認的編碼方式,在python3中默認為utf-8,
在python2中默認為ASCII,我們可以通過指定文件頭來修改默認的編碼
在文件首行寫入包含#號在內的以下內容
# coding:當初文件寫入硬盤時采用的編碼格式
解釋器會先用默認的編碼方式讀取文件的首行內容,由于首行是純英文組成,
而任何編碼方式都可以識別英文字符。
第三個階段:
設置文件頭的作用是保證運行python程序的前兩個階段不亂碼,經過前兩個階段后py文件的內容
都會以unicode的格式存放于內存中。在經歷第三個階段時開始識別python語法,但遇到特定的
語法name='上'(代碼本身也是由unicode格式存的),需要申請內存空間來存儲這個變量,
在python3中,字符串類都是直接使用unicode格式來存儲的。
由于Python2的盛行是早于unicode的,因此在Python2中是按照文件頭指定的編碼來存儲字符串類型的值的,
然后再次取用這個值時會按照默認的uft-8的方式去解碼,不會產生亂碼。但是在cmd指令框中,因為默認編碼方式是GBK,所以解碼時產生亂碼。
(如果文件頭中沒有指定編碼,那么解釋器會按照它自己默認的編碼方式來存儲‘上’),
為了不產生可以在字符串前面加u,則不論頭頂的存儲方式格式是什么,都是以unicode的方式存儲。
這時候可以按照任意方式再去編碼,只要支持輸入內容的類型,再次解碼讀取時用同種類型解碼到unicode則可直接打印成字符。
與python3方式相同了。
文件處理
1.什么是文件
文件是操作系統提供給用戶/應用程序操作硬盤的一個虛擬單位
2.為何要用文件
存取硬盤必須使用文件
3.如何用文件
f=open(文件路徑,打開模式)
f.write(數據)
f.close
每個文件所在地點就像是剝洋蔥,從最外層一層一層剝下來直到找到此文件。絕對路徑就是這整個過程。相對路徑就是我在此文件的上幾層或是同一層,則直接從我這層出發往下剝找到此文件。相比之下相對文件較為簡單輕松找到目標文件,而絕對路徑雖然有些麻煩從頭找起,但是卻能保證找到此文件的準確性。
進行文件處理時,首先需要下達指令操作系統通過文件路徑找到文件并打開進行操作,然后是定義讀寫模式并且有txt和Bytes的區分,再就是讀取的解碼模式。如果需要直接讀取字符模式,需要有encoding='utf-8'的模式去解碼文件內容,因為在pycharm中默認是以utf-8的模式存入txt的文本內容,如果不用相應的編碼去解碼,那么就會安裝window默認的GBK的編碼模式去解碼,那么將會出現亂碼。如果操作文件為圖片,則不需要解碼過程,那么直接定義文件路徑和讀寫模式以及用Bytes模式即可操作文件。在txt文本內容中,將Bytes解碼成unicode的形式,也意味著數據類型從Bytes類型轉換成str類型,那么可以直接進行打印輸出。