1. 程式人生 > >python編碼問題,從隱隱作痛到除去病根

python編碼問題,從隱隱作痛到除去病根

range 一個 test dev 寫代碼 code 字符 all 不同

查閱的資料鏈接

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 cant 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 cant 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編碼問題,從隱隱作痛到除去病根