讀書筆記 流暢的python 文字和位元組序列

2021-10-07 09:15:37 字數 4046 閱讀 3741

基本的編解碼器

編碼問題

處理文字檔案

unicode規範化(比較和排序)

unicode文字排序

unicode資料庫

支援字串和位元組序列的雙模式api

「字元」的最佳定義是unicode字元,從python3的str物件中獲取的元素是unicode字元,相當於從py2的unicode物件中獲取的元素,而不是從py2的str物件中獲取的原始位元組序列。

字元的表示和具體的位元組表述

python3中引入了不可變bytes型別和可變bytearray型別。bytes和bytearray物件的各個元素是介於0-255間的整數(1byte)。切片也是同一型別的二進位制序列。

位元組的字面量表示

byte的構造

可以在enocode是指定errors=***

>>

> city =

'são paulo'

>>

> city.encode(

'utf_8'

) b's\xc3\xa3o paulo'

>>

> city.encode(

'utf_16'

)b'\xff\xfes\x00\xe3\x00o\x00 \x00p\x00a\x00u\x00l\x00o\x00'

>>

> city.encode(

'iso8859_1'

) b's\xe3o paulo'

>>

> city.encode(

'cp437'

) traceback (most recent call last)

: file ""

, line 1,in

file "/.../lib/python3.4/encodings/cp437.py"

, line 12

,in encode return codecs.charmap_encode(

input

,errors,encoding_map) unicodeencodeerror:

'charmap' codec can't encode character '\xe3' in position 1

: character maps to

>>

> city.encode(

'cp437'

, errors=

'ignore'

) b'so paulo'

>>

> city.encode(

'cp437'

, errors=

'replace'

)b's?o paulo'

>>

> city.encode(

'cp437'

, errors=

'xmlcharrefreplace'

) ➏

b'são paulo'

指定errors,如:

octets.decode(『utf_8』, errors=『replace』)

統一字元編碼偵測包 chardet,,它能 識別所支援的 30 種編碼。chardet 是乙個 python 庫,可以在程式中使用,不過它也提供了 命令列工具 chardetect。

utf-16 編碼的序列開頭有幾個額外的位元組b』\xff\xfe』。這就是 bom,即位元組序標記(byte-order mark),指明編碼時使用 intel cpu 的小字節序。

在小字節序裝置中,各個碼位的最低有效位元組在前面:字母 『e』 的碼

位是 u+0045(十進位制數 69),在位元組偏移的第 2 位和第 3 位編碼為 69和 0。

在大字節序 cpu 中,編碼順序是相反的;『e』 編碼為 0 和 69。

utf-8 的一大優勢是,不管裝置使用哪種位元組序,生成的位元組序列始終一致,因此不需要 bom。

儘管如此,某些windows 應用(尤其是 notepad)依然會在 utf-8 編碼的檔案中新增

bom;而且,excel 會根據有沒有 bom 確定檔案是不是 utf-8 編碼,

否則,它假設內容使用 windows **頁(codepage)編碼。

處理文字的最佳實踐是「unicode 三明治」。 意思是,要盡早把輸入(例 如讀取檔案時)的位元組序列解碼成字串。不要依賴預設編碼.

問題:因為 unicode 有組合字元(變音符號和附加到前乙個字元上的記號,列印時作為乙個整 體),所以字串比較起來很複雜。

方法:使用 unicodedata.normalize 函式提供的 unicode 規範化。

** 大小寫摺疊**

大小寫摺疊其實就是把所有文字變成小寫,再做些其他轉換。這個功能由 str.casefold() 方法(python 3.3 新增)支援。

規範化文字匹配函式

nfc_equal 和 fold_equal

方法一:

在 python 中,非 ascii 文字的標準排序方式是使用 locale.strxfrm 函式,根據 locale 模組的文件,這 個函式會「把字串轉換成適合所在區域進行比較的形式」。

方法二:

使用pyuca庫

pyuca 沒有考慮區域設定。如果想定製排序方式,可以把自定義的排序表路徑傳給 collator() 構造方法。pyuca 預設使用專案自帶的 allkeys.txt(這就是 unicode 6.3.0 的「default unicode collation element table」(的副本。

unicode 標準提供了乙個完整的資料庫(許多格式化的文字檔案),不僅包括碼位與字元 名稱之間的對映,還有各個字元的元資料,以及字元之間的關係。例如,unicode 資料庫 記錄了字元是否可以列印、是不是字母、是不是數字,或者是不是其他數值符號。字串 的 isidentifier、isprintable、isdecimal 和 isnumeric 等方法就是靠這些資訊作 判斷的。 str.casefold 方法也用到了 unicode 表中的資訊。 unicodedata 模組中有幾個函式用於獲取字元的元資料。例如,字元在標準中的官方名稱是不是組合字元(如結合波形符構成的變音符號等),以及符號對應的人類可讀數值(不是碼位)。

注:re 模組對 unicode 的支援並不充分。pypi 中有個新開發的 regex 模組,它的最終目的是取代 re 模組,以提供更好的 unicode 支援。

re和os模組中的一些函式能接受字串或位元組序列

正則匹配:re

如果使用位元組序列構建正規表示式,\d 和 \w 等模式只能匹配 ascii 字元;相比之下,如果是字串模式,就能匹配 ascii 之外的 unicode 數字或字母。

前兩個正規表示式是字串型別。 後兩個正規表示式是位元組序列型別。

os函式中的字串和位元組序列

gnu/linux 核心不理解 unicode,為了規避這個問題,os 模組中的所有函式、檔名或路徑名引數既能使用字串,也能 使用位元組序列。如果這樣的函式使用字串引數呼叫,該引數會使用 sys.getfilesystemencoding() 得到的編解碼器自動編碼,然後作業系統會使用相同 的編解碼器解碼。

《流暢的Python》讀書筆記

第1章 python資料模型 通過實現特殊方法,自定義資料型別可以表現得和內建型別一樣 repr 方便除錯和記錄日誌,str 方便使用者看 序列資料型別特殊方法使用最多 第2章 序列構成的陣列 系列型別可分為 可變和不可變 扁平序列和容器序列 列表推導生成器表示式提供了靈活構建和初始化序列的方式 元...

流暢的python讀書筆記

1.雖然也可以用列表推導來初始化元組 陣列或其他序列型別,但是生成器表示式是更好的選擇。這是因為生成器表示式背後遵守了迭代器協議,可以逐個地產出元素,而不是先建立乙個完整的列表,然後再把這個列表傳遞到某個建構函式裡。前面那種方式顯然能夠節省記憶體。生成器表示式的語法跟列表推導差不多,只不過把方括號換...

《流暢的Python》讀書筆記(三)

country code my dict.setdefault key,使用 collections.defaultdict import collections index collections.defaultdict list index hunan changsha index defaul...