關於編碼
(首先了解一下ascii、gb2312、gbk、utf-8、unicode的關系 http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html#_3.4.UTF-8)a.命令行中編碼
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> a='nihao中國'
>>> a
'nihao\xd6\xd0\xb9\xfa' //‘nihao’是按ascii編碼,而中文是按utf-8編碼,這么顯示是正常的,輸出字符實際字節內容,供程序員調試
>>> print a //print 才是輸出給用戶看的內容
nihao中國
>>> b='\xd6\xd0\xb9\xfa'
>>> isinstance(b,unicode) //判斷是否為unicode編碼
False
>>> b1=unicode(b,'gb2312') //轉為unicode字符
>>> isinstance(b1,unicode)
True
>>> print b1
中國
>>> b1
u'\u4e2d\u56fd'
>>> b2=b1.encode('utf-8') //轉為utf-8編碼
>>> isinstance(b2,unicode)
False
>>> print b2
中國
>>> b2
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> b='hi'+u'you' #和Unicode連接,產生Unicode字串
>>> isinstance(b,unicode)
True
>>> b
u'hiyou'
>>> str(b) #內置的str()函數把Unicode字串轉換成ASCII字串
'hiyou'
>>> a=["你好","abnd"]
>>> print a
['\xc4\xe3\xba\xc3', 'abnd']
>>> print a[0]
你好
b.程序中編碼
系統編碼如[a]中所示
當python中間處理非ASCII編碼時,經常會出現如下錯誤: UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)
0x??是超出128的數字,python在默認的情況下認為語言的編碼是ascii編碼,所以無法處理其他編碼,需要設置python的默認編碼為所需要的編碼。
第一種解決方法就是在代碼中添加:
- import sys
- reload(sys)
- sys.setdefaultencoding('utf8') #gb2312,gbk
- print sys.getdefaultencoding() # 輸出當前編碼
(對我的系統和程序沒有起作用)
第二種:
在 python的Lib\site-packages 文件夾下新建一個sitecustomize.py 文件(sitecustomize.py is a special script; Python will try to import it on startup, so any code in it will be run automatically.),輸入:
- import sys
- sys.setdefaultencoding('utf-8')
這樣就能夠自動的設置編碼了。
可以通過第一種方法進行測試。
ps: 為什么要轉碼?是因為不同的系統、不同的平台使用的編碼不一致(最可能導致中文不能正常顯示)。那么,如果你在不同的平台進行輸入輸出操作,首先你要搞清楚 他們的編碼,然后進行轉碼就ok了。
相關的搜集字符串在Python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字符串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。 decode的作用是將其他編碼的字符串轉換成unicode編碼,如str1.decode('gb2312'),表示將gb2312編碼的字符串str1轉換成unicode編碼。 encode的作用是將unicode編碼轉換成其他編碼的字符串,如str2.encode('gb2312'),表示將unicode編碼的字符串str2轉換成gb2312編碼。
1 http://hi.baidu.com/jiangzubin/item/e3e9072660a690d4ee10f1fd
關於中文字符串和split()方法打印中文
>>> a="一 二 三"
>>> a
'\xd2\xbb \xb6\xfe \xc8\xfd'
>>> print a
一 二 三
>>> a.split()
['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
>>> a.split()[0]
'\xd2\xbb'
>>> print a.split() //print顯示編碼,這是問題。或許跟輸出方式有關,看下面的解決辦法(或解釋)
['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
>>> print a.split()[0]
一
>>> print "'%s'" % (",".join(b))
'一,二,三'
為什么打印單個元素就可以,而列表就不行?
print一個對象,是輸出其“為了給人(最終用戶)閱讀”而
設計的輸出形式,那么字符串中的轉義字符需要轉出來,而且
也不要帶標識字符串邊界的引號。
而在命令行下對對象求值,其輸出是為了讓程序員探求其內在
特征,所以輸出結果是對對象的描述。
現在問題來了,一個list對象,本身就是個數據結構,如果要
把它顯示給最終用戶看,而不是用於給程序員調試時,應該如何
“潤色”輸出格式呢?這顯然應該交給程序員去根據應用的需要
來做“潤色”而不是顯示一個用來表示list的方括號,里面卻是
給最終用戶看的“潤色”過的結果。這種蹩腳輸出,對最終用戶
很不知所雲,對程序員調試程序又沒啥意義。
ps:這段還能理解~print結果針對用戶或程序員。就是當我們針對用戶用print輸出對象時,一般程序員需要對其轉義,輸出用戶期望看到的;
當我們在命令行下輸出,默認是給程序員看的,輸出其實質內容,未經轉義。(准確講,並沒有出錯。)
: 我也補充一下。
:
: listobject.c
: PyTypeObject PyList_Type = {
: PyObject_HEAD_INIT(&PyType_Type)
: 0,
: "list",
: sizeof(PyListObject),
: ...
: (reprfunc)list_repr, /* tp_repr */
: 0, /* tp_str */
: ...
: };
:
: list.__str__沒有實現,所以list.__str__ == object.__str__
: 而運行時的object.__str__會去調用list.__repr__(object.c), 而list.__repr__會對自己的元素調用object.__repr__,所以當元素為str類型的話,就是str.__repr__了
ps:程序沒看懂,解說算看懂了吧。
2 還是關於此錯誤
UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)
參考 http://blog.chinaunix.net/uid-10597892-id-2946918.html
特別有用的理解:
3 http://www.360doc.com/content/11/0213/01/2563193_92593666.shtml
On my win7(Python 2.7.3)
>>> s=u"中文" //明顯沒事找事,unicode編碼有必要拉上中文么,中文為uft-8編碼,又來個unicode聲明,亂了吧
>>> print s //看,亂碼了吧
ÖÐÎÄ
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>> print s.encode('utf-8') //本來編碼就混亂了,這里encode也會暈的吧,亂碼
脰脨脦脛
>>> s
u'\xd6\xd0\xce\xc4' //看,unicode + utf-8
>>> print '\xd6\xd0\xce\xc4' //純utf-8編碼
中文
>>> s='中文'
>>> print s
中文
>>> s
'\xd6\xd0\xce\xc4'
4 其他
http://blog.iamzsx.me/show.html?id=81001
http://hi.baidu.com/l4yn3/item/136bd2157b9ed2456926bb83
http://www.zhidaow.com/?p=310
http://www.zhidaow.com/?p=267
http://baike.baidu.com/view/664966.htm
http://www.oschina.net/code/snippet_70229_2348