文件头声明编码
关于python文件头部分知识的讲解
顶部的:# -*- coding: utf-8 -*-或者# coding: utf-8目前有三个作用
如果代码中有中文注释,就需要此声明。
比较高级的编辑器(比如我的emacs),会根据头部声明,将此作为代码文件的格式。
程序会通过头部声明,解码初始化 u"人生苦短",这样的unicode对象,(所以头部声明和代码的存储格式要一致)。
Example1
# -*- coding:utf-8 -*-
su = "人生苦短" #su是一个utf-8格式的字节串
u = s.decode("utf-8") # s被解码为unicode对象,赋给u
sg = u.encode("gbk") # u被编码为gbk格式的字节串,赋给sg
print sg
Note: 不能直接输出decode结果:u = s.decode("utf-8"); print u; 要encode后输出。
但是事实情况要比这个复杂,比如看如下代码:
1 s = "人生苦短"
2 s.encode('gbk')
看!str也能编码,(事实上unicode对象也能解码,但是意义不大)
Note:原理,当对str进行编码时,会先用默认编码将自己解码为unicode,然后在将unicode编码为你指定编码。
这就引出了python2.x中在处理中文时,大多数出现错误的原因所在:python的默认编码,defaultencoding是ascii
看这个例子:
1 # -*- coding: utf-8 -*-
2 s = "人生苦短"
3 s.encode('gbk')
上面的代码会报错,错误信息:UnicodeDecodeError: 'ascii' codec can't decode byte ......
因为你没有指定defaultencoding,所以它其实在做这样的事情:
1 # -*- coding: utf-8 -*-
2 s = "人生苦短"
3 s.decode('ascii').encode('gbk')
Example2
python2.x示例:
>>> ss = '北京市'
>>> type(ss)
>>> us = ss.decode('gbk')
>>> us
u'\u5317\u4eac\u5e02'
>>> type(us)
>>> nus = u'北京市'
>>> nus
u'\u5317\u4eac\u5e02'
>>> ss
'\xb1\xb1\xbe\xa9\xca\xd0'
>>> gbks = nus.encode('gbk')
>>> gbks
'\xb1\xb1\xbe\xa9\xca\xd0'
>>> print(gbks)
北京市
>>> utfs = nus.encode('utf-8')
>>> utfs
'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'
>>> print(utfs)
鍖椾含甯
>>> xx = utfs.decode('utf-8')
>>> type(xx)
ss = '北京市' 采用终端默认的编码形式,windows命名行窗口默认是gbk编码,所以通过ss.decode('gbk')转化成unicode的序列。最后utf-8编码的utfs输出乱码也是因为cmd终端是gdk编码的。
该示例中可以看到“北京市”的三种编码序列:
unicode序列:u'\u5317\u4eac\u5e02'
gbk序列:'\xb1\xb1\xbe\xa9\xca\xd0'
utf-8序列:'\xe5\x8c\x97\xe4\xba\xac\xe5\xb8\x82'
python中设置默认编码defaultencoding
设置defaultencoding的代码如下:
1 reload(sys)
2 sys.setdefaultencoding('utf-8')
如果你在python中进行编码和解码的时候,不指定编码方式,那么python就会使用defaultencoding。
比如上一节例子中将str编码为另一种格式,就会使用defaultencoding。
s.encode("utf-8") 等价于 s.decode(defaultencoding).encode("utf-8")
Note: 这个过程是s先通过defaultencoding解码为unicode,再编码为utf-8类型的编码。
再比如你使用str创建unicode对象时,如果不说明这个str的编码格式,那么程序也会使用defaultencoding。
u = unicode("人生苦短") 等价于 u = unicode("人生苦短",defaultencoding)
代码中字符串的默认编码与代码文件本身的编码一致,但有时候不是,这样就会造成错误。
import sys
print sys.getdefaultencoding()
# 'ascii'
基本上是ascii编码方式(Python脚本文件是由utf-8编码的),由此Python自然调用ascii编码解码程序去处理字符流,当字符流不属于ascii范围内,就会抛出异常(ordinal not in range(128))。
指定文件字符集为utf-8
在文件头部加入以下代码:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
注意:
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。
因此,转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码
代码中字符串的默认编码与代码文件本身的编码一致,为防止特殊情况最好加上上面三行代码。
如:s='中文'
如果是在utf8的文件中,该字符串就是utf8编码,如果是在gb2312的文件中,则其编码为gb2312。这种情况下,要进行编码转换,都需要先用decode方法将其转换成unicode编码,再使用encode方法将其转换成其他编码。通常,在没有指定特定的编码方式时,都是使用的系统默认编码创建的代码文件。