python編碼問題,從隱隱作痛到除去病根
查閱的資料鏈接
python編碼為什麽這麽蛋疼
python2.7手冊str函數
python源文件默認編碼與內部默認編碼
1.源文件默認編碼為ASCII,所以,如果不顯示聲明當前代碼用什麽編碼寫的,python會用ASCII去解析,如果源文件中有UTF-8編碼,由於ASCII不能翻譯UTF8編碼,則會報錯了.
#file test.py 使用UTF8保存 a=‘a‘ b=‘好‘
運行後
SyntaxError: Non-ASCII character ‘\xe5‘ in file test.py on line 2, but no encodi ng declared; see http://python.org/dev/peps/pep-0263/ for details
上面報錯說character ‘\xe5‘是非ASCII碼,因為‘\xe5‘是‘好‘的UTF8字節串的一部分
如下
在編碼為UTF8的終端中打印‘好‘ >>> a=‘好‘ >>> a ‘\xe5\xa5\xbd
所以,當前的源文件是什麽編碼編輯的,一定要聲明出來.比如
#coding=utf-8 #先在這裏聲明 #下面是程序代碼
2.有一點需要註意的是,在終端的命令行模式編輯代碼時,不需要再聲明當前寫代碼時所用的編碼,我猜是因為python在命令行模式時,直接讀取當前系統的編碼
例如,windows的cmd下再查看‘好‘這個字
在編碼為GBK的終端(cmd)打印‘好‘ >>> a=‘好‘ >>> a ‘\xba\xc3‘
可以看到在cmd中,‘好‘是兩個字節,不同於上的三個字節
3.內部默認編碼為ASCII,導致使用一些函數時需要註意,比如str和unicode
有時候,運行一個腳本,比如我們通常用utf8編碼保存腳本,如果在windows的cmd上運行,則print中文時會亂碼,因為cmd的默認編碼是GBK,它解釋UTF8的字節串時,自然會弄的亂七八糟.
那麽如何讓終端打印信息時,不考慮終端的編碼也不亂碼?
1.調整終端默認編碼
2.讓腳本迎合終端的口味,要麽方案a:腳本就保存為GBK的,要麽方案b:在需要終端顯示的地方轉一下碼,我說下b方案
#coding=utf-8 import sys a=‘好‘ #這個文件是保存為UTF8編碼,如果要在cmd上正常顯示,需要轉為GBK, aUnicode = a.decode(‘utf-8‘) #先解碼為unicode,解碼的時候要告訴python,a是一個utf8字節串,不要又以為是ASCII字節串 aGBK=aUnicode.encode(‘GBK‘)#將unicdode編碼的a再編碼為GBK print aGBK
以上有一個小插曲,我直接用a.encode(‘GBK‘)行嗎?這樣是不行的,因為編碼(encode)是針對unicode而言的,必須對unicode編碼,如果硬生生使用類似‘我‘.encode(‘GBK‘),則會報錯的
如下
>>> a=‘好‘ >>> a.encode(‘GBK‘) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xba in position 0: ordinal not in range(128) >>>
看到了吧,python爬出了Unicode解碼異常,python又說‘ascii‘怎麽怎麽樣,為啥啊?
因為python只會對unicode字符串進行encode,如果非要對字節串encode,則它會先把字節串decode,也就是這樣
a.encode(‘GBK‘)==( a.decode(‘默認編碼‘).encode(‘gbk‘) )
上面的unicode解碼異常,也是在進行解碼的時候拋出的,python認為a就是用默認編碼ASCII編碼的,可a是UTF8編碼啊,‘好‘在ASCII中不存在,所以會報錯
3.我不管你終端什麽編碼,終端你都要給我正常顯示.
那就用最直接的unicode編碼啦,讓python自己根據系統的當前編碼進行轉碼打印出來
#coding=utf-8 print u‘我‘
當 print 一個unicode字符串時,打印出來的是unicode對應的系統編碼的字符,從而不會亂碼了
衍生的一個小問題,我就是想看某變量unicode是啥樣的,那就用reper函數(返回一個對象的字符串形式)
>>> a=u‘好‘ >>> a u‘\u597d‘ >>> print repr(a) u‘\u597d‘
說一下str函數
str函數,以字符串的形式返回對象的呈現(在我理解,就是人可以看的呈現),
針對不同的對象,str有不同的操作方法,比如針對於string類型,它會原樣返回
對於function類型,str函數會以字符串的形式返回這個函數在內存中的位置
string類型使用str函數時,註意一點,如果是unicode類型的字符串,一定註意當前的默認編碼
如下,我在cmd,編碼為GBK,python默認編碼為ASCII
>>> a=u‘好‘ >>> str(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: ‘ascii‘ codec can‘t encode character u‘\u597d‘ in position 0 : ordinal not in range(128) >>>
以上對unicode使用str函數時,這個轉換涉及到默認編碼內部首先進行這樣的轉換:unicodeStr.encode(defaultencoding).
如果defaultencoding不是編寫代碼本身的編碼,那就會拋出異常.
所以,要設置defaultencoding,如下
>>> import sys >>> reload(sys) <module ‘sys‘ (built-in)> >>> sys.setdefaultencoding(‘GBK‘) #規定默認編碼為GBK >>> a=u‘啦‘ >>> str(a) #這裏就不會報錯了 ‘\xc0\xb2‘ >>> str(a)==a True
python編碼問題,從隱隱作痛到除去病根