python白皮书(11)—字符编码
1、unicode编码
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,不但要知道它的编码方式,还要安装有对应编码表,否则就可能无法读取或出现乱码。为什么电子邮件和网页都经常会出现乱码,就是因为信息的提供者和信息的读取者使用了不同的编码方式。
如果有一种编码,将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。这就是Unicode编码。
2、 python字符编码
python有str object 和 unicode object 两种字符串, 都可以存放字符的字节编码,但是他们是不同的type,这一点很重要,也是为什么会有encode 和decode。
decode:str -------------------------> Unicode 将str以某种编码转换成unicode
encode:unicode -------------------------> str 将unicode转换成某种编码的str
(1)str_string.decode('codec') 是把str_string转换为unicode_string, codec是源str_string的编码方式;
(2)unicode_string.encode('codec') 是把unicode_string 转换为str_string,codec是目标str_string的编码方式;
(3)str_string.decode('from_codec').encode('to_codec') 可实现不同编码的str_string之间的转换;
>>> t='长城' #<type 'str'>
>>> t
'\xb3\xa4\xb3\xc7'
>>> t.decode('gb2312').encode('utf-8')
'\xe9\x95\xbf\xe5\x9f\x8e'
编码声明
源代码文件中,如果有用到非ASCII字符,则需要在文件头部进行字符编码的声明:
#-*- coding: UTF-8 -*-
读写文件
内置的open()方法打开文件时,read()读取的是str,读取后需要使用正确的编码格式进行decode()。
# coding: UTF-8
f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type 'str'>
# 已知是GBK编码,解码成unicode
u = s.decode('GBK')
# 编码成UTF-8编码的str
f = open('test.txt', 'w')
s = u.encode('UTF-8')
f.write(s)
f.close()
编码方法
# coding:gbk
import sys
import locale
def p(f):
print '%s.%s(): %s' % (f.__module__, f.__name__, f())
# 返回当前系统所使用的默认字符编码
p(sys.getdefaultencoding) # ascii
# 返回用于转换Unicode文件名至系统文件名所使用的编码
p(sys.getfilesystemencoding) # ISO-8859-1
# 获取默认的区域设置并返回元祖(语言, 编码)
p(locale.getdefaultlocale) # ('en_US', 'ISO8859-1')
# 返回用户设定的文本数据编码
p(locale.getpreferredencoding) # ISO-8859-1
一些建议
(1)使用字符编码声明,并且同一工程中的所有源代码文件使用相同的字符编码声明。这点是一定要做到的。
(2)抛弃str,全部使用unicode。按引号前先按一下u最初做起来确实很不习惯而且经常会忘记再跑回去补,但如果这么做可以减少90%的编码问题。如果编码困扰不严重,可以不参考此条。
(3)使用codecs.open()替代内置的open()。如果编码困扰不严重,可以不参考此条。
(4)绝对需要避免使用的字符编码:MBCS/DBCS和UTF-16。