一、python3中str與unicode
在python3中,字符串有兩種形式:str和bytes,兩者區別如下:
unicode string(str類型):以Unicode code points形式存儲(人認識的形式)
byte string(bytes類型):以byte形式存儲(機器認識的形式)
在python3中所定義的所有字符串都是unicode string類型,使用type和isinstance可以判別
而bytes是一個二進制序列對象,你只要你在定義字符串時前面加一個b,就表示你要定義一個bytes類型的字符串對象
但是在定義中文字符串時,你就不能直接在前面加b了,而應該使用encode轉一下
二、python2中str與unicode
而在Python2中,字符串的類型又與Python3不一樣,需要仔細區分
在Python2裏,字符串也只有兩種類型,unicode和str
只有unicode object和非unicode object(其實應該叫str object)的區別:
unicode string(unicode類型):以Unicode code points形式存儲(人認識的形式)
byte string(str類型):以byte形式存儲(機器認識的形式)
當我們直接使用雙引號或單引號包含字符的方式來定義字符串時,就是str字符串對象,比如這樣
而當我們在雙引號或單引號前面加個u,就表明我們定義的是unicode字符串對象,比如這樣
三、如何檢測對象的編碼
所有的字符,在unicode字符集中都有對應的編碼值(code point)
而把這些編碼值按照一定的規則保存成二進制字節碼,就是我們說的編碼方式,常見的有:UTF-8,GB2312等。
也就是說,當我們要將內存中的字符串持久化到硬盤中的時候,都要指定編碼方法,而反過來,讀取的時候,也要指定正確的編碼方法(這個過程叫解碼),不然會出現亂碼。
那問題就來了,當我們知道了其對應的編碼方法,我們就可以正常解碼,但並不是所有時候我們都能知道應該用什麼編碼方式去解碼?
這時候就要介紹到一個python的庫--chardet,使用它之前需要先安裝
python3 -m pip install chardet
chardet有一個detect方法,可以預測其編碼格式
>>> import chardet
>>> chardet.detect('微信公衆號:Python編程時光'.encode('gbk'))
{'encoding': 'GB2312','confidence': 0.99,'language': 'Chinese'}
爲什麼說是預測呢,通過上面的輸出來看,你會看到有一個confidence字段,其表示預測的可信度,或者說成功率。
但是使用它時,若你的字符數較少,就有可能“誤診”),比如只有中文兩個字,就像下面這樣,我們是使用gbk編碼的,使用chardet卻識別成KOI8-R編碼。
所以爲了編碼診斷的準確,要儘量使用足夠多的字符
四、編碼與解碼的區別
編碼和解碼,其實就是str與bytes的相互轉化的過程(Python 2已經遠去,這裏以及後面都只用Python 3舉例)
編碼:encode方法,把字符串對象轉化爲二進制字節序列
解碼:decode方法,把二進制字節序列轉化爲字符串對象
Unicode & Character Encodings in Python
那麼假如我們真知道了其編碼格式,如何來轉成unicode呢?
有兩種方法:
第一種是直接使用decode方法
>>> byte_obj.decode('gbk')
'中文'
>>>
第二種是使用str類來轉
>>> str_obj=str(byte_obj,encoding='gbk')
>>>str_obj
'中文'
>>>
五、如何設置文件編碼
在Python 2中,默認使用的是ASCII編碼來讀取的,因此,我們在使用Python 2的時候,如果你的python文件裏有中文,運行是會報錯的。
SyntaxError:Non-ASCII character '\xe4' in file demo.py
原因就是ASCII編碼表太小,無法解釋中文。
而在Python 3中,默認使用的是uft-8來讀取,所以省了不少的事。
對於這個問題,通常解決方法有兩種:
第一種方法:在python2中,可以使用在頭部指定
可以這樣寫,雖然很好看
# -*- coding: utf-8 -*-
但這樣寫太麻煩了,我通常使用下面兩種寫法
#coding:utf-8
#coding=utf-8
第二種方法:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
這裏在調用sys.setdefaultencoding(‘utf-8’)設置默認的解碼方式之前,執行了reload(sys),這是必須的,因爲python在加載完sys之後,會刪除sys.setdefaultencoding這個方法,我們需要重新載入sys,才能調用sys.setdefaultencoding這個方法