python编码问题及unicode/utf-8编码

python环境中,对原始unicode编码与其它基于unicode的编码字符串进行了显示的区分,因此,当你将不同的编码串混合在一起,但彼此又没有兼容关系的话,就会报编码错误,如下面几种情况:

u'杨晓伟'.encode('utf-8') + u'123'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)

u'杨晓伟'+ '123'
u'u6768u6653u4f1f123'

为什么后面一个,明明是unicode与ascii字符串相加还没有出错呢?且看下面:

s = u'杨晓伟'
u'u6768u6653u4f1f'
chardet.detect(s)
{'confidence': 1.0, 'encoding': 'ascii'}

s = u'杨晓伟'.encode('utf-8')
'xe6x9dxa8xe6x99x93xe4xbcx9f'
chardet.detect(s)
{'confidence': 0.93812499999999999, 'encoding': 'utf-8'}

看见没,unicode字符串经过python检测为ascii编码,所以可以’骗'过Codec(Coder/DECoder得首字母组合),进行拼接。由于以下原因

codec支持的四种耳熟能详的编码方式是:ASCII,ISO8859—1/Latin-1,UTF-8,和UTF-16

在默认编码为ascii的系统或环境中,想要将unicode原始字符串写入文件就“必须”得报错了,而unicode与ascii混合的字符串也’必须‘得报错,因为其内部有codec无法识别的字符,其无法转换成二进制。

Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)

其实,utf-8只是一种处理方法下的unicode编码的不同表现形式,当然也只有utf-8编码器能够将’utf-8‘编码的字符串翻译为原始unicode。

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII相容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件网页及其他储存或传送文字的应用中,优先采用的编码。

UTF-8使用一至四个字节为每个字符编码:

  1. 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
  2. 带有附加符号拉丁文希腊文西里尔字母亚美尼亚语希伯来文阿拉伯文叙利亚文它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
  3. 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
  4. 其他极少使用的Unicode 辅助平面的字符使用四字节编码。

 

发表评论