如下內容說的都是 python 2.x 版本html
咱們看到的輸入輸出都是‘字符’(characters),計算機(程序)並不能直接處理,須要轉化成字節數據(bytes),由於程序只能處理 bytes 數據。
例如:文件、網絡傳輸等,處理的都是 bytes 數據——二進制數字。python
孤立的 byte 是毫無心義的,因此咱們來賦予他們含義。就引入‘字符集’的概念,‘字符集’就是一個碼位(code point)對應的一個字符的表。網絡
該表用於賦予 byte 意義。還須要知道一個點:由於 ASCII 字符集支持的字符太少,不能表示各個國家語言中的字符。因此就發明了
Unicode ——萬國碼,該字符集包含了你能用到的全部的字符。函數
在 python 中字符串分爲兩個對象:str
和 unicode
測試
unicode_obj.encode() ——> bytes ‘編碼’(encode) bytes_obj.decode() ——> unicode ‘解碼’(decode)
UTF-8 是最流行的一種對 Unicode 進行傳播和存儲的編碼方式。因此,多用它做爲編碼方式。編碼
s = 'hello' # str u = u'你好' # unicode back_to_bytes = u.encode('utf-8') back_to_utf8 = back_to_bytes.decode('utf-8') # 或 unicode(s, 'utf-8')
正如前面所說的,計算機只能操做 bytes,因此 Python 在編譯原文件的時候,會先把源文件進行編碼,默認以‘ASCII’進行編碼。這就是爲何若是源文件中帶有‘中文’,須要在源文件的起始行聲明編碼方式。code
完成編碼後,源碼中的全部字符,都變成了 bytes 計算機就能夠進行編譯和處理了。編譯過程:htm
根據這個過程,在本身的代碼中也應該按照這個邏輯處理,意思是:對象
參考:PEP 263 -- Defining Python Source Code Encodingsblog
byte 流中不會包含編碼信息(編碼信息會在:文件的開頭、協議中等地方聲明)
Content-Type:text/html; charset=UTF-8
指明的編碼有多是錯誤的(出現亂碼)
在 python 中處理編碼問題,會出現不少問題,這裏就不一一列舉。
這些問題大都是使用了不匹配的編碼方式進行解碼、編碼形成的。而 python 爲了語法更加簡介,在一些內置方法中,使用了一些隱性轉換。這種隱形的轉換帶了的便捷的同時也會帶來一些非預期的錯誤。下面就一一道來。
a = "abc" + u"bcd"
a = "abc" + u"bcd"
,Python 會如此轉換 "abc".decode(sys.getdefaultencoding()) 而後將兩個 Unicode 字符合並。
str()
和unicode()
,sys.getdefaultencoding()
默認爲:ASCII,這就是爲何str(u'中文')
和unicode('中文')
分別會報錯:UnicodeEncodeError和UnicodeDecodeError。由於ASCII編碼方式,編碼/解碼不了中文(支持的字符有限)。
print
函數print
函數,會對輸出的內容進行編碼,這是由於:所謂的輸出,也是從一個程序到另一個程序。程序之間的交互都是都是傳遞 bytes。比方說print
,就是把數據傳遞給 終端 ,終端也是個程序,因此print
函數就把須要輸出的內容編碼成了 bytes,採用那種編碼方式,就是
由sys.stdout.encoding
參數決定的。
在交互環境下(python、ipython)輸入的數據的編碼則由sys.stdin.encoding
參數決定。參考:What does python print() function actually do?
python 的默認編髮方式爲 ASCII。
如何改變python的默認編碼方式?:
import sys # sys.setdefaultencoding() does not exist, here! reload(sys) # Reload does the trick! sys.setdefaultencoding('UTF8')
爲何要重載sys
模塊?
由於若是在編譯.py
文件的以前,改變默認編碼,會影響Python的編譯。
當編譯完,再重載sys
模塊,它就是變成了第三方模塊,能夠隨便更改,不回影響編譯。setdefaultencoding()
函數才能夠調用。參考:Changing default encoding of Python?
本片文章沒有列舉出常見的異常,由於若是看懂了上面全部的解釋。再按照下面的姿式使用,那麼 python2 中的編碼問題,因該就不會再困擾你了。
Unicode 三明治:儘量的讓你程序處理的文本都爲 Unicode 。以下圖:
瞭解你的字符串。你應該知道你的程序中,哪些是 unicode, 哪些是 byte,對於這些 byte 串。你應該知道,他們的編碼是什麼。(詳情見上述小結第 4 條)
測試 Unicode 支持。使用一些奇怪的符號來測試你是否已經作到了以上幾點。(測試看看你的程序是否支持中文)