Python 编码处理-str与Unicode的区别
一篇关于STR和UNICODE的好文章
整理下python编码相关的内容
注意:以下讨论为Python2.x版本,Py3k的待尝试
开始
用python处理中文时,读取文件或消息,http参数等等
一运行,发现乱码(字符串处理,读写文件,print)
然后,大多数人的做法是,调用encode/decode进行调试,并没有明确思考为何出现乱码
所以调试时最常出现的错误
错误1
Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>UnicodeDecodeError:‘ascii‘codeccan‘tdecodebyte0xe6inposition0:ordinalnotinrange(128)
错误2
Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py",line16,indecode returncodecs.utf_8_decode(input,errors,True)UnicodeEncodeError:‘ascii‘codeccan‘tencodecharactersinposition0-1:ordinalnotinrange(128)
首先
必须有大体概念,了解下字符集,字符编码
ASCII|Unicode|UTF-8|等等
字符编码笔记:ASCII,Unicode和UTF-8
淘宝搜索技术博客-中文编码杂谈
str和unicode
str和unicode都是basestring的子类
所以有判断是否是字符串的方法
defis_str(s): returnisinstance(s,basestring)
str和unicode转换
decode文档
encode文档
str ->decode(‘the_coding_of_str‘)->unicodeunicode->encode(‘the_coding_you_want‘)->str
区别
str是字节串,由unicode经过编码(encode)后的字节组成的
声明方式
s=‘中文‘s=u‘中文‘.encode(‘utf-8‘) >>>type(‘中文‘)<type‘str‘>
求长度(返回字节数)
>>>u‘中文‘.encode(‘utf-8‘)‘\xe4\xb8\xad\xe6\x96\x87‘>>>len(u‘中文‘.encode(‘utf-8‘))6
unicode才是真正意义上的字符串,由字符组成
声明方式
s=u‘中文‘s=‘中文‘.decode(‘utf-8‘)s=unicode(‘中文‘,‘utf-8‘) >>>type(u‘中文‘)<type‘unicode‘>
求长度(返回字符数),在逻辑中真正想要用的
>>>u‘中文‘u‘\u4e2d\u6587‘>>>len(u‘中文‘)2
结论
搞明白要处理的是str还是unicode,使用对的处理方法(str.decode/unicode.encode)
下面是判断是否为unicode/str的方法
>>>isinstance(u‘中文‘,unicode)True>>>isinstance(‘中文‘,unicode)False >>>isinstance(‘中文‘,str)True>>>isinstance(u‘中文‘,str)False
简单原则:不要对str使用encode,不要对unicode使用decode(事实上可以对str进行encode的,具体见最后,为了保证简单,不建议)
>>>‘中文‘.encode(‘utf-8‘)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>UnicodeDecodeError:‘ascii‘codeccan‘tdecodebyte0xe4inposition0:ordinalnotinrange(128) >>>u‘中文‘.decode(‘utf-8‘)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py",line16,indecode returncodecs.utf_8_decode(input,errors,True)UnicodeEncodeError:‘ascii‘codeccan‘tencodecharactersinposition0-1:ordinalnotinrange(128)
不同编码转换,使用unicode作为中间编码
#s是code_A的strs.decode(‘code_A‘).encode(‘code_B‘)
文件处理,IDE和控制台
处理流程,可以这么使用,把python看做一个水池,一个入口,一个出口
入口处,全部转成unicode,池里全部使用unicode处理,出口处,再转成目标编码(当然,有例外,处理逻辑中要用到具体编码的情况)
读文件 外部输入编码,decode转成unicode 处理(内部编码,统一unicode) encode转成需要的目标编码 写到目标输出(文件或控制台)
IDE和控制台报错,原因是print时,编码和IDE自身编码不一致导致
输出时将编码转换成一致的就可以正常输出
>>>printu‘中文‘.encode(‘gbk‘)????>>>printu‘中文‘.encode(‘utf-8‘)中文
建议
规范编码
统一编码,防止由于某个环节产生的乱码
环境编码,IDE/文本编辑器,文件编码,数据库数据表编码
保证代码源文件编码
这个很重要
py文件默认编码是ASCII,在源代码文件中,如果用到非ASCII字符,需要在文件头部进行编码声明文档
不声明的话,输入非ASCII会遇到的错误,必须放在文件第一行或第二行
File"XXX.py",line3SyntaxError:Non-ASCIIcharacter‘\xd6‘infilec.pyonline3,butnoencodingdeclared;seehttp://www.python.org/peps/pep-0263.htmlfordetails
声明方法
#-*-coding:utf-8-*-或者#coding=utf-8
若头部声明coding=utf-8,a=‘中文‘其编码为utf-8
若头部声明coding=gb2312,a=‘中文‘其编码为gbk
so,同一项目中所有源文件头部统一一个编码,并且声明的编码要和源文件保存的编码一致(编辑器相关)
在源代码用作处理的硬编码字符串,统一用unicode
将其类型和源文件本身的编码隔离开,独立无依赖方便流程中各个位置处理
ifs==u‘中文‘: #而不是s==‘中文‘ pass#注意这里s到这里时,确保转为unicode
以上几步搞定后,你只需要关注两个unicode和你设定的编码(一般使用utf-8)
处理顺序
1.Decodeearly2.Unicodeeverywhere3.Encodelater
相关模块及一些方法
获得和设置系统默认编码
>>>importsys>>>sys.getdefaultencoding()‘ascii‘ >>>reload(sys)<module‘sys‘(built-in)>>>>sys.setdefaultencoding(‘utf-8‘)>>>sys.getdefaultencoding()‘utf-8‘
str.encode(‘other_coding‘)
在python中,直接将某种编码的str进行encode成另一种编码str
#str_A为utf-8str_A.encode(‘gbk‘) 执行的操作是str_A.decode(‘sys_codec‘).encode(‘gbk‘)这里sys_codec即为上一步sys.getdefaultencoding()的编码
‘获得和设置系统默认编码‘和这里的str.encode是相关的,但我一般很少这么用,主要是觉得复杂不可控,还是输入明确decode,输出明确encode来得简单些(个人观点)
chardet
文件编码检测,下载
>>>importchardet>>>f=open(‘test.txt‘,‘r‘)>>>result=chardet.detect(f.read())>>>result{‘confidence‘:0.99,‘encoding‘:‘utf-8‘}
\u字符串转对应unicode字符串
>>>u‘中‘u‘\u4e2d‘ >>>s=‘\u4e2d‘>>>prints.decode(‘unicode_escape‘)中 >>>a=‘\\u4fee\\u6539\\u8282\\u70b9\\u72b6\\u6001\\u6210\\u529f‘>>>a.decode(‘unicode_escape‘)u‘\u4fee\u6539\u8282\u70b9\u72b6\u6001\u6210\u529f‘
以上就是对Python编码处理的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!