PYTHON字符編碼

Python 的默認編碼是 ASCII(編者注:Python 2.x)html

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

因此在 Python 源代碼文件中若是不顯示地指定編碼的話,將出現語法錯誤。python

#test.py
print "你好"

上面是 test.py 腳本,運行 python test.py 就會包以下錯誤:linux

File 「test.py」, line 1
SyntaxError: Non-ASCII character ‘\xe4′ in file
test.py on line 1, but no encoding declared;
see http://www.python.org/ps/pep-0263.html for details

爲了在源代碼中支持非 ASCII 字符,必須在源文件的第一行或者第二行顯示地指定編碼格式:編程

# coding=utf-8

或者windows

#!/usr/bin/python
# -*- coding: utf-8 -*-

在 Python 中和字符串相關的數據類型,分別是 str、unicode 兩種,他們都是 basestring 的子類,可見 str 與 unicode 是兩種不一樣類型的字符串對象。編程語言

basestring
      /  \ 
     /    \
   str    unicode

對於同一個漢字」好」,用 str 表示時,它對應的就是 utf-8 編碼的 ‘\xe5\xa5\xbd’,而用 unicode 表示時,他對應的符號就是 u’\u597d’,與 u"好" 是等同的。須要補充一點的是,str 類型的字符串具體的編碼格式是 UTF-8 仍是 GBK ,仍是其餘格式,根據操做系統相關。好比在 Windows 系統中,cmd 命令行中顯示的:函數

# windows終端
>>> a = '好'
>>> type(a)
<type 'str'>
>>> a
'\xba\xc3'

而在Linux系統的命令行中顯示的是:測試

# linux終端
>>> a='好'
>>> type(a)
<type 'str'>
>>> a
'\xe5\xa5\xbd'

>>> b=u'好'
>>> type(b)
<type 'unicode'>
>>> b
u'\u597d'

不管是 Python 3.x、Java 仍是其餘編程語言,Unicode 編碼都成爲語言的默認編碼格式,而數據最後保存到介質中的時候,不一樣的介質可有用不一樣的方式,有些人喜歡用 UTF-8,有些人喜歡用 GBK,這都無所謂,只要平臺統一的編碼規範,具體怎麼實現並不關心。編碼

輸入圖片說明

str與unicode的轉換 那麼在 Pytho n中 str 和 unicode 之間是如何轉換的呢?這兩種類型的字符串類型之間的轉換就是靠這兩個方法 decode 和 encode。操作系統

輸入圖片說明

#從str類型轉換到unicode
s.decode(encoding)   =====>  <type 'str'> to <type 'unicode'>
#從unicode轉換到str
u.encode(encoding)   =====>  <type 'unicode'> to <type 'str'>

>>> c = b.encode('utf-8')
>>> type(c)
<type 'str'>
>>> c
'\xe5\xa5\xbd'

>>> d = c.decode('utf-8')
>>> type(d)
<type 'unicode'>
>>> d
u'\u597d'

這個 ‘\xe5\xa5\xbd’ 就是 unicode u’好’經過函數 encode 編碼獲得的 UTF-8 編碼的 str 類型的字符串。反之亦然,str 類型的 c 經過函數 decode 解碼成 unicode 字符串 d 。

str(s)與unicode(s)

str(s) 和 unicode(s) 是兩個工廠方法,分別返回 str 字符串對象和 unicode 字符串對象,str(s) 是 s.encode(‘ascii’) 的簡寫。實驗:

>>> s3 = u"你好"
>>> s3
u'\u4f60\u597d'
>>> str(s3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

上面 s3 是 unicode 類型的字符串,str(s3) 至關因而執行 s3.encode(‘ascii’) ,由於」你好」兩個漢字不能用 ascii 碼來表示,因此就報錯了,指定正確的編碼:s3.encode(‘gbk’) 或者 s3.encode(「utf-8」) 就不會出現這個問題了。相似的 unicode 有一樣的錯誤:

>>> s4 = "你好"
>>> unicode(s4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)
>>>

unicode(s4) 等效於 s4.decode(‘ascii’),所以要正確的轉換就要正確指定其編碼 s4.decode(‘gbk’) 或者 s4.decode(「utf-8」)。

亂碼

全部出現亂碼的緣由均可以歸結爲字符通過不一樣編碼解碼在編碼的過程當中使用的編碼格式不一致,好比:

# encoding: utf-8

>>> a='好'
>>> a
'\xe5\xa5\xbd'
>>> b=a.decode("utf-8")
>>> b
u'\u597d'
>>> c=b.encode("gbk")
>>> c
'\xba\xc3'
>>> print c
��

utf-8 編碼的字符’好’佔用3個字節,解碼成 Unicode 後,若是再用 gbk 來解碼後,只有 2 個字節的長度了,最後出現了亂碼的問題,所以防止亂碼的最好方式就是始終堅持使用同一種編碼格式對字符進行編碼和解碼操做。

輸入圖片說明

其餘技巧

對於如 unicode 形式的字符串(str類型):

s = 'id\u003d215903184\u0026index\u003d0\u0026st\u003d52\u0026sid'

轉換成真正的 unicode 須要使用:

s.decode('unicode-escape')

測試:

>>> s = 'id\u003d215903184\u0026index\u003d0\u0026st\u003d52\u0026sid\u003d95000\u0026i'
>>> print(type(s))
<type 'str'>
>>> s = s.decode('unicode-escape')
>>> s
u'id=215903184&index=0&st=52&sid=95000&i'
>>> print(type(s))
<type 'unicode'>
>>>
相關文章
相關標籤/搜索