《Fluent Python》讀書筆記-Text versus Bytes

概覽

????"string"的概念很簡單,就是字符的序列。但是怎么定義字符是一個問題。在python3,str是由Unicode字符組成,而在python2里str是由原始的byte字符組成。
????Unicode標準把字符的標識和字符的二進制表示區(qū)分開來:

  • 字符的標識,即碼位(code point),是一個從0到1,114,111的數(shù)字,在Unicode標準里是以U+為前綴的4到6位的16進制數(shù)字。如字母A的碼位是U+0041。
  • 實際的一個字符的二進制表示是由具體使用的編碼(encoding)決定。如字母A在UTF-8編碼里是單個字節(jié)\x41而在UTF-16LE編碼下是兩個字節(jié)\x41\x00。
    ????從碼位轉換字節(jié)是encoding,從字節(jié)轉換到碼位是decoding。

字符編碼的各式各樣的問題

????本章后面講了很多因為字符編碼產生的問題,在目前做過的項目中基本沒碰到過,感覺主要出現(xiàn)在像希臘語,葡萄牙語還有泰米爾語這類語言上,也沒去深入研究,簡單做下總結。

  • 有些編碼包含的字符只是Unicode的一個子集,當把一個Unicode字符轉換到目標編碼時,如果目標編碼不包含這個字符的定義,則會報UnicodeEncodeError,可以通過在encode方法中加入error參數(shù),對錯誤進行忽略或者做一些處理。
  • 如果二進制編碼有錯,不是一個有效的編碼,則在把二進制編碼轉換到Unicode字符時,會報UnicodeDecodeError,也可以通過在decode方法中加入error參數(shù),對錯誤進行忽略或者做一些處理。
  • 從python3開始,源碼的默認編碼采用UTF-8,而python2的默認編碼是ASCII,意味著#!coding: utf8不需要再加了。
  • 作者討論了下是不是能從二進制序列里發(fā)現(xiàn)編碼方式,答案是不可以。但是可以通過一些特殊的規(guī)則大概確定一下,作者介紹了個chardet的項目。
  • BOM是用來標識大端序和小端序的,對于UTF-16是需要的,但是對于UTF-8不是必須的,python沒有使用BOM來判斷一個文件是否是UTF-8。
  • 如果使用python默認的編碼,可能會出問題,比如用UTF-8編碼寫一個文件,但是讀的時候沒指定編碼,在Linux上沒問題,但是可能在Windows上就有問題。最好是在所有的操作上都明確指定編碼格式。
  • 因為組合字符的原因,字符串比較會有些問題,打印出來是一樣的字符,可能實際的編碼不一樣,python提供了一些normalize方法進行歸一化,不過作者也提到像google就是直接把這些變音符給去掉。
  • 在字符串排序時有可能也會出現(xiàn)問題,作者推薦了個PyUCA。
  • python中有一個完整的Unicode database,記錄了每個字符的各方面的信息。
  • python的接口可以支持str和bytes的輸入參數(shù),但是根據(jù)參數(shù)類型不同,結果也不同。
  • python提供了struct模塊去對打包在一起的bytes進行拆包。
>>> import struct
>>> fmt = '<3s3sHH' #
>>> with open('filter.gif', 'rb') as fp: ... img = memoryview(fp.read()) # ...
>>> header = img[:10] #
>>> bytes(header) # b'GIF89a+\x02\xe6\x00'
>>> struct.unpack(fmt, header) # (b'GIF', b'89a', 555, 230)
>>> del header #
>>> del img
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容