正如其他语言一样,在Python的世界里也有有字符的编解码问题;有的在命令行回显时出现,有的在读取文件时出现,有的在执行命令时出现,有的在读取数据库时出现,不尽相同。
注:如未特别申明下文中的编解码均特指字符串的编解码。
之所以会出现编解码问题是因为程序不同处理过程中与外界输入、输出所有使用的编码规则不一致所造成的,所以要解决编解码问题就要先理清怎么使得所有的编解码都一致。包括python文件、python系统、db、普通文件等等。
1、Python文件的编码
python文件中的字符编码由2个地方决定:
一个是保存文件时的编码格式,比如:用utf-8格式保存的源文件,这个可以在各编辑器或IDE中设置;这个决定文件保存的编码格式
一个是python源文件头部设置的编码申明,如:# –– coding: utf-8 –– ;这个决定文件加载时解码的格式
我们在保存和设置python文件编码时务必要让2者保持一致即可,通常一般都设置为utf-8。
2、Python系统的编码
python系统的默认编码为unicode,它不是一个具体的编码实现,可以理解为python中各编码的中间变量,所有其它编码进行转换的时候,首先都要转换成unicode,然后在由unicode转成成目标编码格式。
如何得到unicode对象?
s=u'中国'
s=unicode('中国')
s='中国'.decode(code) ##code => utf-8, gbk
通常我们在需要显示转码的时候会给定一个编解码的格式,如:utf-8、gbk;而在某些情况下会用到隐式的转码格式,比如打印内容时没有提供给我们设置编码的接口,这时就用到python系统中的设定目标编码格式;(因为unicode不是最终编码必须要转换成可回显的编码格式)
python默认的编码取值
1、系统的默认编码
2、IDE设置的编码
3、代码设置的编码
优先级越来越高,如何通过代码设置python系统默认的编码方式?
import sys
print sys.getdefaultencoding()
reload(sys)
sys.setdefaultencoding("UTF-8") ##设置默认编码方式为utf-8
print sys.getdefaultencoding()
所以务必在设置默认编码方式的时候要设置成与文件保存的编解码一致,这样就可以避免打印出乱码,或者打印时需要预先进行编码转换。
3、数据库们的编码
python在读取数据库时可以指定连接数据的编码格式,具体需要使用什么格式取决于数据库保存时的编码格式;当数据库的保存格式与我们python中设定的编码不一致时,在读取时就需要注意转换了。
比如:mysql的数据库编码为gbk,而我们的python程序编码使用的utf-8,那么在连接数据库时需要使用gbk进行连接,
conn=MySQLdb.Connect(host="localhost",user="root",passwd="root",db="tw",charset="gbk")
这样读取出来的字符编码是解码后的unicode,我们可以直接进行相关操作。
4、普通文件的编码
python中读写文件可以直接使用open,file等函数,但是也提供了更专业的模块来帮助我们写入指定编码类型的文件;这就用到了codecs模块了。
import codecs
of = codecs.open('test.txt', 'rw', 'utf8')
这样不论读写都是按照指定的编码来进行的,同样该模块还支持其他字符的编码处理
a = '中国'
coder = codecs.lookup('utf-8') ##创建指定编码的编码器
coder.decode(a) ##使用编码器解码
5、IDE中的编码
IDE中一般设置编辑器环境为utf-8,workdir为utf-8;前者决定文件保存时的编码方式,后者决定程序运行时的环境编码。
6、encode、decode、unicode
这3个函数是python默认自带的,通常我们使用这3个函数就可以很好的处理工作中遇到的字符编码问题;
a = '中国'
b = a.decode('gbk') ##解码gbk为unicode
c = b.encode('utf-8') ##unicode编码成utf-8
d = unicode(a) ##使用python环境默认编码来解码成unicode,即sys.getdefaultencoding决定
7、获取编码类型
str = '中国'
for code in ['utf-8', 'gbk']:
if str.decode(code, 'ignore')==str.decode(code, 'replace'):
print code
break
for code in ['utf-8', 'gbk']:
try:
str.decode(code)
print code
break
except(e):
pass
import chardet
print chardet.detect(str)