首页 > 关于python2中的一个编码问题

关于python2中的一个编码问题

# -*- coding: UTF-8 -*-
import chardet
import sys
reload(sys) 
sys.setdefaultencoding('utf-8') 

a = u'\xe5\xb0\x8f\xe4\xb8\x89'
print type(a)
print a
print a.encode('utf-8')
b = u'小三'
print type(b)
print b
print b.encode('utf-8')
c = '\xe5\xb0\x8f\xe4\xb8\x89'
print chardet.detect(c)
print type(c)
print c

首先有几个基本概念我是了解的
* 第一行的注释指定的就是当前python脚本中所有字符串也就是str类型的编码格式
* python默认的解码格式是ascii需要用后面的三句话更改默认的解码格式也为utf-8
* str类型是需要解码之后再重新编码的
* unicode类型是不需要解码可以重新编码成其他的编码格式的

然后再来看下上面那段脚本的输出

<type 'unicode'>
小三
小三
<type 'unicode'>
小三
小三
{'confidence': 0.7525, 'encoding': 'utf-8'}
<type 'str'>
小三

我现在比较不解的是为什么

print a
print a.encode('utf-8')

这两句没有输出正确的结果,是乱码

print b
print b.encode('utf-8')

却输出了正确的结果

因为事实上u\xe5\xb0\x8f\xe4\xb8\x89就是小三的unicode码,为什么u\xe5\xb0\x8f\xe4\xb8\x89编码成utf-8依然无法正确输出小三,但是u小三这个unicode就可以正确输出并且不需要编码成utf-8都可以正确输出?

求各位高人解答

如何得到\xe5\xb0\x8f\xe4\xb8\x89这一串字节码的

# encoding: UTF-8
import re
import sys   
print sys.getdefaultencoding()
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入   
sys.setdefaultencoding('utf-8') 

pattern1 = re.compile(r'<div>.*?</div>')
pattern2 = re.compile(r'<div>.*</div>')
result = pattern1.findall('aa<div>test1</div>bb<div>test2</div><div>小三</div>cc')
print result
result = pattern2.findall('aa<div>test1</div>bb<div>test2</div><div>小三</div>cc')
print result

然后输出结果就是

ascii
['<div>test1</div>', '<div>test2</div>', '<div>\xe5\xb0\x8f\xe4\xb8\x89</div>']
['<div>test1</div>bb<div>test2</div><div>\xe5\xb0\x8f\xe4\xb8\x89</div>']

不愧是 Python 2 用户,和 Python 2 自己一样分不清什么是 Unicode 什么是已编码文本。

带 u 前缀的,类型是 Unicode。Unicode 意味着什么呢?它的最小单位是字符而非字节。unicode 对象内部是怎么存储代表这些字符的字节、用的什么编码方式,都是实现相关的,你不用管,也应该管不了。

所以,u'\xe5\xb0\x8f\xe4\xb8\x89' 是什么呢?它是包含六个字符的 unicode 字符串。\xe5 这种转义以两位十六进制数的形式指定了该字符的码点,亦即 U+00e5。查字符映射表或者 Unicode 文档可知,它叫 「LATIN SMALL LETTER A WITH RING ABOVE」,书写出来就是「å」。

>>> import unicodedata                      
>>> unicodedata.name(u'\xe5')
'LATIN SMALL LETTER A WITH RING ABOVE'

再看 '\xe5\xb0\x8f\xe4\xb8\x89' 是什么呢?Python 2 傻傻分不清楚,叫它 str。在 Python 3 中它才得到一个恰当的名字,叫 bytes。也就是说,它只是一堆字节。它所包含的数据已经通过某种方式编码过了。这里你知道编码方式是 UTF-8 字符编码。你也可以通过 pickle 模块将一个 Python 对象编码(或称序列化)成一堆字节。我在这里写的这段话会被浏览器按照 HTTP 规范编码成一大坨字节,然后通过网络发送给服务器。sf 的服务器按照 HTTP 规范来解码,于是它取得了其中的数据。然后它还要把这些数据再编码成另一种形式的二进制,送给数据库存起来。

这就是已编码的二进制数据,不是字符串。只是也许,某个 bytes 对象里包含的数据是某种形式编码过的字符串而已。


sf 什么时候才能取消 Ctrl-b 快捷键的拦截啊,让人特别不爽 :-(


看到一篇关于 Unicode 在程序语言中的表示的不错的文章,于是来更新一下。文章讨论的是 Go 语言,其字符串处理和 Python 2 是一样的糟糕。


“小三”用utf-8 编码后 得到的结果就是 小ä

【热门文章】
【热门文章】