千锋教育-做有情怀、有良心、有品质的职业教育机构

Python2.x中的编码问题

来源:千锋教育
发布时间:2023-11-05 19:37:15
分享

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

声明:本站部分稿件版权来源于网络,如有侵犯版权,请及时联系我们。

相关推荐

  • 用Python开发一个简单的猜数字游戏 本文介绍如何使用Python制作一个简单的猜数字游戏。游戏规则玩家将猜测一个数字。如果猜测是正确的,玩家赢。如果不正确,程序会提示玩家所猜的数字与实际数字相比是“大(high)”还是“小(low)”,
  • 使用 Python 函数进行模块化 你是否对函数、类、方法、库和模块等花哨的编程术语感到困惑?你是否在与变量作用域斗争?无论你是自学成才的还是经过正式培训的程序员,代码的模块化都会令人困惑。但是类和库鼓励模块化代码,因为模块化代码意味着
  • Python语言自带的数据结构有哪些 Python作为一种脚本语言,其要求强制缩进,使其易读、美观,它的数据类型可以实现自动转换,而不需要像C、Java那样给变量定义数据类型,使其编写非常方便简单,所以广受大家的欢迎。现如今,Python
  • 用Python和Conu测试容器 越来越多的开发人员使用容器开发和部署他们的应用。这意味着可以轻松地测试容器也变得很重要。Conu(containerutilities的简写)是一个Python库,让你编写容器测试变得简单。本文向你介
  • Python循环应该怎么写? 说到处理循环,我们习惯使用for,while等,比如依次打印每个列表中的字符:lis=['I','love','python']foriinlis:pr
  • 优化 Python 程序的内存占用 Python的垃圾回收机制通过引用计数来决定一个对象要不要被回收。当一个对象被引用次数为0时,它就会被作为垃圾回收从而释放Python内存。但有些情况下,我们的代码可能在不经意间导致某些实际上我们不再