參考鏈接: Python中的字節對象與字符串
1.常見字符串編碼錯誤?
在使用Python讀文件時經常遇到編碼問題引起的錯誤,比如:?
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 30: illegal multibyte sequence?
遇到這種異常時可以通過讀文件時規定編碼方式來解決,如下:?
with open('zhengfu.txt','r',encoding='UTF-8') as read_zhengfu:?
如果文件中還包含其他非UTF-8編碼的字符,或者無關的特殊字符,可以再加入一個參數,如下:?
with open('zhengfu.txt','r',encoding='UTF-8',errors='ignore') as read_zhengfu:?
有時讀文件時還會遇到一種問題就是第一行數據的開頭多了一串‘'\ufeff’字符。比如:?
?
如果用print(list[0])是看不到這個字符的。對這個沒有研究過, 如果要去掉這串字符的話,可以使用‘utf-8-sig’這種編碼方式:?
with open('user_dict_2.txt','r',encoding='utf-8-sig') as read_dict:?
但是我在寫入文件時設置為‘utf-8-sig’格式時不起作用,寫入的文件中還是有這個字符。?
另外,在對字符串進行匹配的時候,'\ufeff’會影響字符串的匹配結果。?
?
2.字符串編碼?
關于計算機內部如何表示字符串,為何又要創造這么多種編碼方式,推薦閱讀 https://www.cnblogs.com/hhwu/p/9529942.html 這篇博客里作者講的很明白,這里主要是想匯總介紹Python中的字符串函數。?
2.1 chr()函數和ord()函數?
chr()函數是將一個整數返回一個對應的字符,ord()函數則相反,其返回一個字符的數值表示(返回的是Unicode值的十進制表示)。在Python3.6的版本中,chr()中整數的范圍不再是0到255,擴大到了1114111,大于改值時,報ValueError錯誤。而ord()函數中只能接受單字符串作為其輸入,否則會報TypeError錯誤。?
print(chr(65)) #輸出'A'
print(ord('A')) #輸出65?
2.2 Unicode編碼?
雖然Python 3的內存中Unicode來保存字符串,但為了節省內存,Python3內部使用3種方式存儲Unicode字符。具體分為以下三種:?
Latin-1一個字符占一個字節。比如ASCII碼值UCS-2一個字符占兩個字節。常見的中文都占用2個字節UCS-4一個字符占四個字節。比較偏僻的中文還有emoj表情通常占用4個字節。
python中提供了內置函數來查看每個字符串對象的編碼類型。如果一個字符串的所有字符都能用ASCII碼來表示,那么該字符串使用Latin-1。如果字符串中出現了中文,則采用UCS-2編碼即可。如果字符串中有一些生僻字或者emoj表情的話,則必須使用UCS-4編碼。注意在Python中,一個字符串中的所有字符只能采用一種編碼方式,不能混用。因為一旦混用,那么字符串中每個字符所占的字節數必定不同,那么字符串將不能使用下標進行快速直接讀取。下面來具體看看字符串具體在內存中所占用的字節數。?
字符串的長度和該字符串所占的字節數不相同。字符串的長度可以直接通過len()f方法來求,而字符串在內存中實際所占的字節數需要通過getsizeof()函數來計算。?
import sys
#返回字符串所占字節數,返回78
print(sys.getsizeof('你好'))
#返回字符串長度,長度為2
print(len("你好"))?
從以下的實驗結果可以發現,一個空字符串在內存中就占了49個字節的內存。?
?
Python內存中的數據,不管是int型還是字符串,都會額外占用一些內存空間保存一些信息,這些信息保存了字符串的一些基礎信息,并且能夠決定字符串所能進行的操作。Python一般會為字符串分配49到80個字節的額外空間。?
下面這段代碼分別展示了字符‘a’在三種不用的Unicode編碼中所占的字節數。?
import sys
#latin-1編碼時'a'所占的字節數,其結果為:1
print(sys.getsizeof('ab')-sys.getsizeof('b'))
#ucs-2編碼時'a'所占的字節數,其結果為:2
print(sys.getsizeof('a你好')-sys.getsizeof('你好'))
#ucs-4編碼時'a'所占的字節數,其結果為:4
print(sys.getsizeof('a?')-sys.getsizeof('?'))