当前位置:天才代写 > tutorial > Python教程 > Python 编码处理惩罚之 str与Unicode的区别与利用

Python 编码处理惩罚之 str与Unicode的区别与利用

2017-11-02 08:00 星期四 所属: Python教程 浏览:799

用python处理惩罚中文,读取文件或动静时,假如发明乱码(字符串处理惩罚,读写文件,print),大大都人的做法是,挪用encode/decode举办调试,并没有明晰思考为何呈现乱码, 本日我们来接头一下如那里理惩罚编码问题。

留意: 以下接头为Python2.x版本, Py3k下未测试

调试时最常呈现的错误

错误1

Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe6 in position 0: ordinal not in range(128)

错误2

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode     return codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: ordinal not in range(128)

首先

必需有概略观念,相识下字符集,字符编码

ASCII | Unicode | UTF-8 | 等等

字符编码条记:ASCII,Unicode和UTF-8

str 和 unicode

str和unicode都是basestring的子类

所以有判定是否是字符串的要领

def is_str(s):     return isinstance(s, basestring) 

str和unicode 转换

str  -> decode(‘the_coding_of_str‘) -> unicode unicode -> 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 (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe4 in position 0: ordinal not in range(128)  
>>> u‘中文‘.decode(‘utf-8‘) 
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode     return codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: ordinal not in range(128)

差异编码转换,利用unicode作为中间编码

#s是code_A的str s.decode(‘code_A‘).encode(‘code_B‘)

文件处理惩罚,IDE和节制台

处理惩罚流程,可以这么利用,把python看做一个水池,一个进口,一个出口

进口处,全部转成unicode, 池里全部利用unicode处理惩罚,出口处,再转成方针编码(虽然,有破例,处理惩罚逻辑中要用到详细编码的环境)

读文件  外部输入编码,decode转成unicode  处理惩罚(内部编码,统一unicode)  encode转成需要的方针编码  写到方针输出(文件或节制台) 

IDE和节制台报错,原因是print时,编码和IDE自身编码纷歧致导致

#p#分页标题#e#

输出时将编码转换成一致的就可以正常输出

>>> print u‘中文‘.encode(‘gbk‘) ???? 
>>> print u‘中文‘.encode(‘utf-8‘) 中文

发起

类型编码

统一编码,防备由于某个环节发生的乱码

情况编码,IDE/文本编辑器, 文件编码,数据库数据表编码

担保代码源文件编码

这个很重要

py文件默认编码是ASCII, 在源代码文件中,假如用到非ASCII字符,需要在文件头部举办编码声明 文档

不声明的话,输入非ASCII会碰着的错误,必需放在文件第一行或第二行

File "XXX.py", line 3 SyntaxError: Non-ASCII character ‘\xd6‘ in file c.py on line 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

声明要领

# -*- coding: utf-8 -*- 可能 #coding=utf-8

若头部声明coding=utf-8, a = ‘中文‘ 其编码为utf-8

若头部声明coding=gb2312, a = ‘中文‘ 其编码为gbk

so, 同一项目中所有源文件头部统一一个编码,而且声明的编码要和源文件生存的编码一致(编辑器相关)

在源代码用作处理惩罚的硬编码字符串,统一用unicode

将其范例和源文件自己的编码隔分开, 独立无依赖利便流程中各个位置处理惩罚

if s == u‘中文‘:  #而不是 s == ‘中文‘     pass #留意这里 s到这里时,确保转为unicode

以上几步搞定后,你只需要存眷两个 unicode和 你设定的编码(一般利用utf-8)

处理惩罚顺序

1. Decode early 2. Unicode everywhere 3. Encode later 

相关模块及一些要领

得到和配置系统默认编码

>>> import sys 
>>> 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-8 str_A.encode(‘gbk‘)  执行的操纵是 str_A.decode(‘sys_codec‘).encode(‘gbk‘) 这里sys_codec即为上一步 sys.getdefaultencoding() 的编码 

‘得到和配置系统默认编码‘和这里的str.encode是相关的,但我一般很少这么用,主要是以为巨大不行控,照旧输入明晰decode,输出明晰encode来得简朴些

chardet

文件编码检测,下载

>>> import chardet 
>>> f = open(‘test.txt‘,‘r‘) 
>>> result = chardet.detect(f.read()) 
>>> result {‘confidence‘: 0.99, ‘encoding‘: ‘utf-8‘}

\u字符串转对应unicode字符串

>>> u‘中‘ u‘\u4e2d‘  
>>> s = ‘\u4e2d‘ 
>>> print s.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‘

 

    关键字:

天才代写-代写联系方式