Python中文字符的理解:str()、repr()、print
都說Python人不把文字編碼這塊從頭到尾、從古至今全研究通透的話是完全玩不轉的。我終於深刻的理解到了。通宵了好幾夜,各種試驗,print、print再print,中文還是既得不到也輸不出。
看了網上幾乎所有主要的相關文章,還是沒搞定。沉靜下來開始反思:是他們寫的不好,還是我理解的不好?所以我決定,再加深程度,一步一個腳印地研究這個問題,不忽略任何一個小細節的理解。先從字符串在Python中最基本的原理理解起。
首先說明一下,我的開發環境是:
python --version : 2.7 OS: Windows 7 (32bit) IDE: Sublime3, IDLE, Windows cmd命令行
Python 字符串的存儲
先看一段代碼,這是在IDLE命令行中幾個簡單的交互:
>>> 'hello' 'hello' >>> print 'hello' hello >>> '你好' '\xc4\xe3\xba\xc3' >>> print '你好' 你好
(都知道在python的命令行里,直接輸入一個變量會顯示它的值,直接輸入一個復雜對象會給你顯示它的對象類型和內存地址)
從上面可以看出,變量時英文的話不管直接輸入還是print結果都一樣。可是為什么直接輸入變量
和print變量
會顯示不一樣的東西呢?
原來,python 2系是絕對英文友好
的。中文對於它來說,只存儲為一串編碼而不是原文。\xc4\xe3\xba\xc3
這種東西對於中國python人來說是再熟悉不過的東西了,沒事就蹦出來幾次。最逗的是,我查了半天,\x$$
這種東西到底是什么編碼,是utf-8還是gb2312?竟然沒找到什么明確的說法,這個一會兒再說了。
話說回來,為什么'你好'
和print '你好'
結果會不一樣呢?
在查看print
官方文檔時發現,在python里面print是一個非常厲害的小家伙:它能把幾乎任何常見類型的對象打印成一串文字,甚至包括列表、字典、元組等等。這在別的語言里是不可理解的,所以給從其他語言轉過來的人埋了個大坑。
總結:Python中出現的任何中文,雖然我們在編輯器里看到的是中文,但是背地里全是一串編碼。千萬不要輕易信任print!print xx
給你顯示出來的,其實並不是xx的真實面貌!
至於這個編碼是什么格式,unicode還是utf-8之類,一會再說。
Python中的str()
和repr()
原生函數
好多人都知道str()能把123數字轉成字符串,python里的str()甚至還能把列表、字典等對象轉成字符串。這都好理解,可是一旦把str()
和repr()
放在一起,大家就全都不淡定了-_-!
來看一段代碼,仍是在IDLE里交互:
>>> str('hello') 'hello' >>> repr('hello') "'hello'" >>> str('你好') '\xc4\xe3\xba\xc3' >>> repr('你好') "'\\xc4\\xe3\\xba\\xc3'"
先看前兩句:英文的'hello'在str()后仍是'hello',可是在repr()后就變成了"'hello'"。這就說明,str()返回的就是字符串本身,而repr()雖然返回的也是字符串,但它是一個標准字符串
,官方解釋比較繞,我來解釋下吧。repr
是representation及描述的意思,不是對人的描述,而是對python機器的描述,也就是它會將某物返回一個它在python中的描述
。說人話:repr(obj)
告訴我們obj這個變量在背地里是什么樣子,在背地里是怎么被python處理被python"玩弄"的。
在python里,我們總會被眼睛欺騙。編輯器里顯示的東西,並不總是它原本的面貌。python為了方便,總是表面上一套,背地里又一套。
再來理解后兩句:中文的'你好'在str()后變成了編碼'\xc4\xe3\xba\xc3',在repr()后變成了"'\xc4\xe3\xba\xc3'"。`都加上了轉移符變成
\,相當於把字符串中的內容都“標准化”了。至於
'變成
"`只是為了說明repr()返回的是一個經過處理的新字符串。
print后的str()和repr()
來看代碼:
>>> print str('你好') 你好 >>> print repr('你好') '\xc4\xe3\xba\xc3'
之前str('你好')顯示的是'\xc4\xe3\xba\xc3'
,而一經過print,就變成了正確的'你好'。上面說過了,命令行里直接輸入一個變量,顯示的是它在python后台存儲的數據;而用print出來的東西,會顯出出盡量友好、讓人能看懂的東西。
理解了這個,對print這兩個結果的不同,也就全然理解了。然后也就放棄print作為考據的心了。
另外,以上代碼的交互,再windows系統cmd中,結果是一樣的。