python2的编解码的几个问题:

(1)两种数据类型unicode 和 str。

unicode-->str 的过程是编码,可以用encode('utf8')这种方式表示,也可以用str()把unicode变成str类型,

另外,str-->unicode 是解码过程,unicode(str),或者str.decode('utf8') 都可以。

但是python2中系统默认的编码是ASCII码,即使你在编辑.py 文件里声明了coding是utf8,那么在执行str(u‘\uXXXX’) 或者 unicode()时,默认还是使用ASCII码进行编解码。

除非使用代码改变system的default encoding。

python的unicode编码 python2 unicode_ico

如果变量是英文的,相应的编解码test如下:

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

importsysprint(sys.getdefaultencoding())#定义a1是英文 str类型
a1 = "hello world"
print "-----a1--------"
printa1printtype(a1)printrepr(a1)#str(str类型)直接返回str类型
print "-----b1--------"b1=str(a1)printb1printtype(b1)printrepr(b1)#unicode(str类型)返回通过ASCII解码方式成unicode
print "-----c1--------"c1=unicode(a1)printc1printtype(c1)printrepr(c1)#用decode方式,把str解码成unicode,对应c1
print "-----d1--------"d1= a1.decode('utf8')printd1printtype(d1)printrepr(d1)#定义a2是英文 unicode类型
print "-----a2--------"a2= u'hello world'
printa2printtype(a2)printrepr(a2)#str(unicode类型)相当于用默认的ASCII码编码成str
print "-----b2--------"b2=str(a2)printb2printtype(b2)printrepr(b2)#unicode unicode类型)不变
print "-----c2--------"c2=unicode(a2)printc2printtype(c2)printrepr(c2)#用encode编码,对应b2部分
print "-----d2--------"d2= a2.encode('utf8')printd2printtype(d2)printrepr(d2)

运行结果:

ascii-----a1--------hello world
'hello world'
-----b1--------hello world
'hello world'
-----c1--------hello worldu'hello world'
-----d1--------hello worldu'hello world'
-----a2--------hello worldu'hello world'
-----b2--------hello world
'hello world'
-----c2--------hello worldu'hello world'
-----d2--------hello world
'hello world'

View Code

相对应的,如果变量是中文的,那么相应的编解码结果如下:

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

#-*- coding:utf-8 -*-
importsysprint(sys.getdefaultencoding())#定义a1是英文 str类型
a1 = "I am 熊猫"
print "-----a1--------"
printa1printtype(a1)printrepr(a1)#str(str类型)直接返回str类型
print "-----b1--------"b1=str(a1)printb1printtype(b1)printrepr(b1)##unicode(str类型)返回通过ASCII解码方式成unicode#print "-----c1--------"#c1 = unicode(a1) #运行结果:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 5: ordinal not in range(128)#print c1#print type(c1)#print repr(c1)
#用decode方式,把str解码成unicode,对应c1
print "-----d1--------"d1= a1.decode('utf8')printd1printtype(d1)printrepr(d1)#定义a2是英文 unicode类型
print "-----a2--------"a2= u'I am 熊猫'
printa2printtype(a2)printrepr(a2)## str(unicode类型)相当于用默认的ASCII码编码成str#print "-----b2--------"#b2 = str(a2) #运行结果:UnicodeEncodeError: 'ascii' codec can't encode characters in position 5-6: ordinal not in range(128)#print b2#print type(b2)#print repr(b2)
#unicode unicode类型)不变
print "-----c2--------"c2=unicode(a2)printc2printtype(c2)printrepr(c2)#用encode编码,对应b2部分
print "-----d2--------"d2= a2.encode('utf8')printd2printtype(d2)printrepr(d2)
运行结果:
ascii-----a1--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'
-----b1--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'
-----d1--------I am 熊猫u'I am \u718a\u732b'
-----a2--------I am 熊猫u'I am \u718a\u732b'
-----c2--------I am 熊猫u'I am \u718a\u732b'
-----d2--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'

View Code

对于带有中文的部分,如果修改相应的系统默认编码,那么使用str或者unicode也不会出错:

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

#-*- coding:utf-8 -*-
importsysprint(sys.getdefaultencoding())
reload(sys)
sys.setdefaultencoding('utf8')print(sys.getdefaultencoding())#定义a1是英文 str类型
a1 = "I am 熊猫"
print "-----a1--------"
printa1printtype(a1)printrepr(a1)#str(str类型)直接返回str类型
print "-----b1--------"b1=str(a1)printb1printtype(b1)printrepr(b1)#unicode(str类型)返回通过ASCII解码方式成unicode
print "-----c1--------"c1=unicode(a1)printc1printtype(c1)printrepr(c1)#用decode方式,把str解码成unicode,对应c1
print "-----d1--------"d1= a1.decode('utf8')printd1printtype(d1)printrepr(d1)#定义a2是英文 unicode类型
print "-----a2--------"a2= u'I am 熊猫'
printa2printtype(a2)printrepr(a2)#str(unicode类型)相当于用默认的ASCII码编码成str
print "-----b2--------"b2=str(a2)printb2printtype(b2)printrepr(b2)#unicode unicode类型)不变
print "-----c2--------"c2=unicode(a2)printc2printtype(c2)printrepr(c2)#用encode编码,对应b2部分
print "-----d2--------"d2= a2.encode('utf8')printd2printtype(d2)printrepr(d2)

运行结果:

ascii
utf8-----a1--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'
-----b1--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'
-----c1--------I am 熊猫u'I am \u718a\u732b'
-----d1--------I am 熊猫u'I am \u718a\u732b'
-----a2--------I am 熊猫u'I am \u718a\u732b'
-----b2--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'
-----c2--------I am 熊猫u'I am \u718a\u732b'
-----d2--------I am 熊猫
'I am \xe7\x86\x8a\xe7\x8c\xab'

View Code

(2)python2,当unicode和str 相连时,默认的,Python2会按照默认编码,把str先变成unicode进行相连。

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

>>>print u'hello'+ '熊猫'Traceback (most recent call last):
File"", line 1, in UnicodeDecodeError:'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)

View Code

这里python默认把‘熊猫’按照ASCII解码成unicode,失败。指明'熊猫'的解码方式,可以成功。

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

>>> print u'hello'+ '熊猫'.decode('utf8')
hello熊猫

View Code

(3)当使用print时,print A 相当于 sys.stdout.write(str(A))

python的unicode编码 python2 unicode_Code_12

Python2.7中调用print打印var 变量时,操作系统会对var做一定的字符处理:

如果var是str类型的变量,则直接将var变量交付给终端进行显示;

如果var变量是unicode类型,则操作系统首先将var编码成str类型的对象(编码格式取决于stdout的编码格式),然后再交由终端进行显示。

在终端显示时,如果str类型的变量的编码方式和终端设置的编码方式不一致,很可能会出现乱码问题。

以下分情况进行用代码进行实验:

变量是str类型的,在不同terminal下运行结果:

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

文件1: utf8编码的str类型的打印py2_utf8.py

文件2: gbk编码的str类型的打印py2_gbk.py

以上两个文件,在两种终端运行:1). 在pycharm上执行,pycharm相当于sys.stdout.encoding 是UTF8的终端。2). 在windows cmd上执行,cmd的编码方式是gbk#-*- coding:utf8 -*-#py2_utf8.py

a= "I am 熊猫"
printaprintrepr(a)printtype(a)

在pycharm上,运行结果正常:

文件中定义的a,在内存中是utf8编码的字节码流,传到操作系统,操作系统不做任何操作,传给终端,终端按照pycharm终端的utf8解码,编解码对应,所以输出正常。

I am 熊猫'I am \xe7\x86\x8a\xe7\x8c\xab'

在windows cmd上运行:

c:\Python27>python D:\python_project\for_python2\py2_utf8.py

I am 鐔婄尗'I am \xe7\x86\x8a\xe7\x8c\xab'

文件中变量是utf8编码的字节流,到终端按照gbk解码,所以解码出来乱码。

View Code

变量是unicode类型的,在不同terminal下运行结果:

python的unicode编码 python2 unicode_python_02

python的unicode编码 python2 unicode_python2默认编码_03

1. 文件以utf8 编码存储,py2_utf8_unicode.py2. 文件以gbk编码存储,py2_gbk_unicode.py#-*- coding:utf8 -*-#py2_utf8_unicode.py
b= u'I am 熊猫'
printbprintrepr(b)printtype(b)
Pycharm 结果:
I am 熊猫
u'I am \u718a\u732b'
CMD结果:
c:\Python27>python D:\python_project\for_python2\py2_utf8_unicode.py
I am 熊猫
u'I am \u718a\u732b'
#-*- coding:gbk -*-#py2_gbk_unicode.py
b= u'I am 熊猫'
printbprintrepr(b)printtype(b)
Pycharm下:
C:\Python27\python.exe D:/python_project/for_python2/py2_gbk_unicode.py
I am 熊猫
u'I am \u718a\u732b'
CMD下:
c:\Python27>python D:\python_project\for_python2\py2_gbk_unicode.py
I am 熊猫
u'I am \u718a\u732b'

View Code

(4)print list和dict时中文显示编码问题

python的unicode编码 python2 unicode_python_02

#-*-coding:utf-8 -*-
a={'name': 'english'}
b={'name': '中文'}print "a=", aprint "b=", bimportjson
result= json.dumps(b, encoding='UTF-8', ensure_ascii=False)print "b=", result
pycharm中运行结果:
a= {'name': 'english'}
b= {'name': '\xe4\xb8\xad\xe6\x96\x87'}
b= {"name": "中文"}

View Code