1. 程式人生 > >七、編碼、文件

七、編碼、文件

轉換 不用 必須 charm 保存數據 str close 穩定 可能

一、編碼

1.1:內存和硬盤

  • CPU: 從內存中讀取程序的指令,然後解碼並運行程序;
  • 硬盤: 永久保存數據;
  • 內存: 臨時存儲數據,任何程序運行都需事先加載到內存;
  • 應用軟件: 調用操作系統提供的接口;間接地使用計算機硬件,加載到內存中;
  • 操作系統: 控制硬件,提供系統調用接口,加載到內存中;

1.2:文本編輯器存取文件的原理  

  例如(nodepad++,pycharm,word等),打開編輯器就可以啟動一個進程,是在內存中的,所以在編輯器編寫的內容也都是存放在內存中的,斷電後數據就丟失了。因而需要保存在硬盤上,點擊保存按鈕或快捷鍵,就把內存中的數據保存到了硬盤上。在這一點上,我們編寫的py文件(沒有執行時),跟編寫的其他文件沒有什麽區別,都只是編寫一堆字符而已。

1.3:python解釋器執行py文件的原理

例如python 、test.py:

  第一階段:python解釋器啟動,此時就相當於啟動了一個文本編輯器;

  第二階段:python解釋器相當於文本編輯器,去打開test.py,從硬盤上將test.py的文件內容讀入到內存中;

  第三階段:python解釋器執行剛剛加載到內存中的test.py的代碼(在該階段,即執行時,才會識別python的語法,執行到字符串時,會開辟內存空間存放字符串);

python解釋器與文本編輯器相同點:python解釋器是解釋執行文件內容的,因而python解釋器具備讀py文件的功能,這一點與文本編輯器一樣;

python解釋器與文本編輯器不同點:文本編輯器將文件內容讀入內存後,是為了顯示/編輯,而python解釋器將文件內容讀入內存後,是為了執行(識別python的語法);

1.3:編碼解釋

  計算機想要工作必須通電,高低電平(高電平即二進制數1,低電平即二進制數0),計算機只認識數字,讓計算機讀懂人類的字符就必須經過:字符---------(翻譯過程)-------------數字,實際就是一個字符如何對應一個特定數字的標準,這個標準稱之為字符編碼。

  1.一個python文件中的內容是由一堆字符組成的(python文件未執行時)

  2.python中的數據類型字符串是由一串字符組成的(python文件執行時)

1.5:編碼的發展史

階段一:

  1. 現代計算機起源於美國,最早誕生也是基於英文考慮的ASCII;
  2. ASCII:一個Bytes代表一個字符(英文字符/鍵盤上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字符;
  3. ASCII最初只用了後七位,127個數字,已經完全能夠代表鍵盤上所有的字符了(英文字符/鍵盤的所有其他字符);
  4. 後來為了將拉丁文也編碼進了ASCII表,將最高位也占用了;

階段二:

  1. 為了滿足中文,中國人定制了GBK;
  2. GBK:2Bytes代表一個字符,為了滿足其他國家,各個國家紛紛定制了自己的編碼,日本把日文編到Shift_JIS裏,韓國把韓文編到Euc-kr裏;

階段三:

  1. 各國有各國的標準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼;
  2. 於是產生了unicode, 統一用2Bytes代表一個字符, 2**16-1=65535,可代表6萬多個字符,因而兼容萬國語言;
  3. 但對於通篇都是英文的文本來說,這種編碼方式無疑是多了一倍的存儲空間(二進制最終都是以電或者磁的方式存儲到存儲介質中的);
  4. 於是產生了UTF-8,對英文字符只用1Bytes表示,對中文字符用3Bytes;

階段四:

  1. unicode:簡單粗暴,多有的字符都是2Bytes,優點是字符--數字的轉換速度快;缺點是占用空間大。
  2. utf-8:精準,可變長,優點是節省空間;缺點是轉換速度慢,因為每次轉換都需要計算出需要多長Bytes才能夠準確表示。
  3. 內存中使用的編碼是unicode,用空間換時間(程序都需要加載到內存才能運行,因而內存應該是越快越好)
  4. 硬盤中或網絡傳輸用utf-8,保證數據傳輸的穩定性。
技術分享圖片
1: 所有程序,最終都要加載到內存,程序保存到硬盤不同的國家用不同的編碼格式,但是到內存中我們為了兼容萬國(計算機可以運行任何國家的程序原因在於此),統一且固定使用unicode,
2: 這就是為何內存固定用unicode的原因,你可能會說兼容萬國我可以用utf-8啊,可以,完全可以正常工作,之所以不用肯定是unicode比utf-8更高效啊(uicode固定用2個字節編碼
3:utf-8則需要計算),但是unicode更浪費空間,沒錯,這就是用空間換時間的一種做法,而存放到硬盤,或者網絡傳輸,都需要把unicode轉成utf-84: 因為數據的傳輸,追求的是穩定,高效,數據量越小數據傳輸就越靠譜,於是都轉成utf-8格式的,而不是unicode。
View Code

1.6:字符編碼轉換

  • 文件從內存刷到硬盤的操作簡稱存文件
  • 文件從硬盤讀到內存的操作簡稱讀文件
  • 亂碼:存文件時就已經亂碼 或者 存文件時不亂碼而讀文件時亂碼

技術分享圖片技術分享圖片

ascii:數字,字母 特殊字符。
字節:8位表示一個字節。
字符:是你看到的內容的最小組成單位。
abc : a 一個字符。
中國:中 一個字符。
a : 0000 1011

unicode: 萬國碼
起初:
    a : 0000 1011 0000 1011

中: 0000 1011 0000 1111
升級:
    a : 0000 1011 0000 1011 0000 1011 0000 1011

中: 0000 1011 0000 1111 0000 1011 0000 1011

utf-8:最少用8位表示一個字符。
a: 0000 1011
歐洲: 0000 1011 0000 1011
亞洲中:0000 1011 0000 1011 0000 1011

gbk:國標
a: 0000 1011
中文:0000 1011 0000 1011 兩個字節。
  • 不同編碼之間的二進制是不能互相識別的。
  • 對於文件的存儲,及傳輸不能是unicode的編碼。
    python3x
int
bool
bytes:內部編碼方式:(非unicode,utf-8,gbk.gb2312...)
str : 內部編碼方式unicode
list
dict
tuple

bytes:內部編碼方式:(非unicode,utf-8,gbk.gb2312...)
str : 內部編碼方式unicode

對於字母

str:

  • 表現形式:s1 = ‘alex‘
  • 內部編碼:unicode

bytes:

  • 表現形式:s2 = b‘alex‘
  • 內部編碼:非unicode

對於中文

str:

  • 表現形式:s1 = ‘中國‘
  • 內部編碼:unicode

bytes:

  • 表現形式:b1 = b‘\xe4\xb8\xad\xe5\x9b\xbd‘
  • 內部編碼:非unicode

例子:

unicode和utf-8之間的轉換:

s1 = alex
#將alex從unicode編碼轉換為utf-8
b1 = s1.encode(utf-8)
print(b1)
#輸出結果:
balex
s1 = alex
b1 = balex
print(s1.capitalize())
print(b1.capitalize())
#輸出結果:
Alex
bAlex
s2 = 中國
b2 = s2.encode(utf-8)
print(b2)
#輸出結果:
b\xe4\xb8\xad\xe5\x9b\xbd

unicode----->utf-8------>unicode

s1 = alex
# str ---> bytes encode 編碼
b1 = s1.encode(utf-8)
print(b1)
#bytes---> str  decode 解碼
s2 = b1.decode(utf-8)
print(s2)
#輸出結果:
balex
alex

Unicode、gbk、utf-8之間的轉換:

s1 = alex
b2 = s1.encode(gbk)
s3 = b2.decode(gbk)
print(b2)
print(s3)
#輸出結果:
balex
alex
s1 = alex
b1 = s1.encode(utf-8)
s2 = b1.decode(gbk)
print(s2)
#輸出結果:
alex

utf-8、gbk之間的轉換

s4 = 中國
b4 = s4.encode(utf-8) # utf-8 bytes
print(b4)
b6 = b4.decode(utf-8).encode(gbk)
print(b6)
#輸出結果:
b\xe4\xb8\xad\xe5\x9b\xbd   #bytes類型的utf-8一個中文3個字節
b\xd6\xd0\xb9\xfa         #bytes類型的gbk一個中文2個字節

二、文件

七、編碼、文件