Python2.x中的编码问题
1.str和unicode
str和unicode都是basestring的子类。严格意义上说,str其实是字节串,它是unicode经过编码后的字节组成的序列。对UTF-8编码的str'汉'使用len()函数时,结果是3,因为实际上,UTF-8编码的'汉'=='\xE6\xB1\x89'。
unicode才是真正意义上的字符串,对字节串str使用正确的字符编码进行解码后获得,并且len(u'汉')==1。
再来看看encode()和decode()两个basestring的实例方法,理解了str和unicode的区别后,这两个方法就不会再混淆了:
13#coding:UTF-8
u=u'汉'
printrepr(u)#u'\u6c49'
s=u.encode('UTF-8')
printrepr(s)#'\xe6\xb1\x89'
u2=s.decode('UTF-8')
printrepr(u2)#u'\u6c49'
#对unicode进行解码是错误的
#s2=u.decode('UTF-8')
#同样,对str进行编码也是错误的
#u2=s.encode('UTF-8')
需要注意的是,虽然对str调用encode()方法是错误的,但实际上Python不会抛出异常,而是返回另外一个相同内容但不同id的str;对unicode调用decode()方法也是这样。很不理解为什么不把encode()和decode()分别放在unicode和str中而是都放在basestring中,但既然已经这样了,我们就小心避免犯错吧。
2.字符编码声明
源代码文件中,如果有用到非ASCII字符,则需要在文件头部进行字符编码的声明,如下:
1#-*-coding:UTF-8-*-
实际上Python只检查#、coding和编码字符串,其他的字符都是为了美观加上的。另外,Python中可用的字符编码有很多,并且还有许多别名,还不区分大小写,比如UTF-8可以写成u8。参见http://docs.python.org/library/codecs.html#standard-encodings。
另外需要注意的是声明的编码必须与文件实际保存时用的编码一致,否则很大几率会出现代码解析异常。现在的IDE一般会自动处理这种情况,改变声明后同时换成声明的编码保存,但文本编辑器控们需要小心:)
3.读写文件
内置的open()方法打开文件时,read()读取的是str,读取后需要使用正确的编码格式进行decode()。write()写入时,如果参数是unicode,则需要使用你希望写入的编码进行encode(),如果是其他编码格式的str,则需要先用该str的编码进行decode(),转成unicode后再使用写入的编码进行encode()。如果直接将unicode作为参数传入write()方法,Python将先使用源代码文件声明的字符编码进行编码然后写入。
14#coding:UTF-8
f=open('test.txt')
s=f.read()
f.close()
printtype(s)#
#已知是GBK编码,解码成unicode
u=s.decode('GBK')
f=open('test.txt','w')
#编码成UTF-8编码的str
s=u.encode('UTF-8')
f.write(s)
f.close()
另外,模块codecs提供了一个open()方法,可以指定一个编码打开文件,使用这个方法打开的文件读取返回的将是unicode。写入时,如果参数是unicode,则使用open()时指定的编码进行编码后写入;如果是str,则先根据源代码文件声明的字符编码,解码成unicode后再进行前述操作。相对内置的open()来说,这个方法比较不容易在编码上出现问题。
20#coding:GBK
importcodecs
f=codecs.open('test.txt',encoding='UTF-8')
u=f.read()
f.close()
printtype(u)#
f=codecs.open('test.txt','a',encoding='UTF-8')
#写入unicode
f.write(u)
#写入str,自动进行解码编码操作
#GBK编码的str
s='汉'
printrepr(s)#'\xba\xba'
#这里会先将GBK编码的str解码为unicode再编码为UTF-8写入
f.write(s)
f.close()
4.与编码相关的方法
sys/locale模块中提供了一些获取当前环境下的默认编码的方法。
31#coding:gbk
importsys
importlocale
defp(f):
print'%s.%s():%s'%(f.__module__,f.__name__,f())
#返回当前系统所使用的默认字符编码
p(sys.getdefaultencoding)
#返回用于转换Unicode文件名至系统文件名所使用的编码
p(sys.getfilesystemencoding)
#获取默认的区域设置并返回元祖(语言,编码)
p(locale.getdefaultlocale)
#返回用户设定的文本数据编码
#文档提到thisfunctiononlyreturnsaguess
p(locale.getpreferredencoding)
#\xba\xba是'汉'的GBK编码
#mbcs是不推荐使用的编码,这里仅作测试表明为什么不应该用
printr"'\xba\xba'.decode('mbcs'):",repr('\xba\xba'.decode('mbcs'))
#在笔者的Windows上的结果(区域设置为中文(简体,中国))
#sys.getdefaultencoding():gbk
#sys.getfilesystemencoding():mbcs
#locale.getdefaultlocale():('zh_CN','cp936')
#locale.getpreferredencoding():cp936
#'\xba\xba'.decode('mbcs'):u'\u6c49'
以上内容为大家介绍了Python2.x中的编码问题,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。
相关推荐HOT
更多>>pythonfor循环是什么
pythonfor循环是什么在做遍历的时候,对于一些数据的反复循环执行,我们会用到for循环的语句。可以说这是新手入门必学的语句之一,在很多基础循...详情>>
2023-11-13 07:46:36pythoncontextmanager()的转换
python中contextmanager()的转换1、说明当发出请求时,requests库会在将请求实际发送到目标服务器之前准备该请求。请求准备包括像验证头信息和...详情>>
2023-11-13 06:34:35python使用items()遍历键值对
python使用items()遍历键值对字典可以用来存储各种方式的信息,所以有很多方式可以通过字典的所有键值对、键或值。说明1、即使通过字典,键值对...详情>>
2023-11-13 04:24:15python实例方法中self的作用
python实例方法中self的作用说明1、无论是创建类的构造方法还是实例方法,最少要包含一个参数self。2、通过实例的self参数与对象进行绑定,程序...详情>>
2023-11-13 03:46:48