encode和decode的妙用

爲何會報錯「UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)」?本文就來研究一下這個問題。html

字符串在Python內部的表示是unicode編碼,所以,在作編碼轉換時,一般須要以unicode做爲中間編碼,即先將其餘編碼的字符串解碼(decode)成unicode,再從unicode編碼(encode)成另外一種編碼。 python

decode的做用是將其餘編碼的字符串轉換成unicode編碼,如str1.decode('gb2312'),表示將gb2312編碼的字符串str1轉換成unicode編碼。 git

encode的做用是將unicode編碼轉換成其餘編碼的字符串,如str2.encode('gb2312'),表示將unicode編碼的字符串str2轉換成gb2312編碼。 編程

所以,轉碼的時候必定要先搞明白,字符串str是什麼編碼,而後decode成unicode,而後再encode成其餘編碼網絡

代碼中字符串的默認編碼與代碼文件自己的編碼一致。 ui

如:s='中文'編碼

若是是在utf8的文件中,該字符串就是utf8編碼,若是是在gb2312的文件中,則其編碼爲gb2312。這種狀況下,要進行編碼轉換,都須要先用decode方法將其轉換成unicode編碼,再使用encode方法將其轉換成其餘編碼。一般,在沒有指定特定的編碼方式時,都是使用的系統默認編碼建立的代碼文件。 spa

若是字符串是這樣定義:s=u'中文'code

則該字符串的編碼就被指定爲unicode了,即python的內部編碼,而與代碼文件自己的編碼無關。所以,對於這種狀況作編碼轉換,只須要直接使用encode方法將其轉換成指定編碼便可。htm

若是一個字符串已是unicode了,再進行解碼則將出錯,所以一般要對其編碼方式是否爲unicode進行判斷:

isinstance(s, unicode)  #用來判斷是否爲unicode 

用非unicode編碼形式的str來encode會報錯 

 如何得到系統的默認編碼? 

#!/usr/bin/env python
#coding=utf-8
import sys
print sys.getdefaultencoding()  

該段程序在英文WindowsXP上輸出爲:ascii 

在某些IDE中,字符串的輸出老是出現亂碼,甚至錯誤,實際上是因爲IDE的結果輸出控制檯自身不能顯示字符串的編碼,而不是程序自己的問題。 

如在UliPad中運行以下代碼:

s=u"中文"
print s 

會提示:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)。這是由於UliPad在英文WindowsXP上的控制檯信息輸出窗口是按照ascii編碼輸出的(英文系統的默認編碼是ascii),而上面代碼中的字符串是Unicode編碼的,因此輸出時產生了錯誤。

將最後一句改成:print s.encode('gb2312')

則能正確輸出「中文」兩個字。

若最後一句改成:print s.encode('utf8')

則輸出:\xe4\xb8\xad\xe6\x96\x87,這是控制檯信息輸出窗口按照ascii編碼輸出utf8編碼的字符串的結果。

unicode(str,'gb2312')與str.decode('gb2312')是同樣的,都是將gb2312編碼的str轉爲unicode編碼 

使用str.__class__能夠查看str的編碼形式

原理說了半天,最後來個包治百病的吧:)

複製代碼代碼以下:


#!/usr/bin/env python 
#coding=utf-8 
s="中文" 

if isinstance(s, unicode): 
#s=u"中文" 
print s.encode('gb2312') 
else: 
#s="中文" 
print s.decode('utf-8').encode('gb2312')

作網絡編程的時候,常常須要把接收到的數據用16進制的方式打印出來,方便查看。今天發如今Python下有這樣一個簡單的方法。

 

>>> "hello".encode("hex") 
'68656c6c6f'

 

相應的還能夠

>>> '68656c6c6f'.decode("hex") 
'hello'

 

查了一下手冊,還有這些codec可用

Codec

Aliases

Operand type

Purpose

base64_codec base64, base-64 byte string Convert operand to MIME base64
bz2_codec bz2 byte string Compress the operand using bz2
hex_codec hex byte string Convert operand to hexadecimal representation, with two digits per byte
idna
Unicode string Implements RFC 3490. New in version 2.3. See alsoencodings.idna
mbcs dbcs Unicode string Windows only: Encode operand according to the ANSI codepage (CP_ACP)
palmos
Unicode string Encoding of PalmOS 3.5
punycode
Unicode string Implements RFC 3492. New in version 2.3.
quopri_codec quopri, quoted-printable, quotedprintable byte string Convert operand to MIME quoted printable
raw_unicode_escape
Unicode string Produce a string that is suitable as raw Unicode literal in pythonsource code
rot_13 rot13 Unicode string Returns the Caesar-cypher encryption of the operand
string_escape
byte string Produce a string that is suitable as string literal in python source code
undefined
any Raise an exception for all conversions. Can be used as the system encoding if no automatic coercion between byte and Unicode strings is desired.
unicode_escape
Unicode string Produce a string that is suitable as Unicode literal in pythonsource code
unicode_internal
Unicode string Return the internal representation of the operand
uu_codec uu byte string Convert the operand using uuencode
zlib_codec zip, zlib byte string Compress the operand using gzip
相關文章
相關標籤/搜索