百科狗-知识改变命运!
--

Python2.x中的编码问题

百变鹏仔1年前 (2023-11-21)阅读数 24#技术干货
文章标签方法

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'

Python2.x中的编码问题

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培训机构:开发教育。

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)