资讯专栏INFORMATION COLUMN

python unicode 编码整理

longshengwang / 3073人阅读

摘要:如果统一规定每个字符用个或者个字节来存储,那么每个英文字符都必然需要额外到个,这对存储是很大的浪费。因此对于英语字母,编码和码是相同的。中文中文输出这里同样可以知道,中存放的是文件保存的编码的码。

unicode 与 utf-8 的关系 unicode 是 character set

character set 是把每个字符对应成数字的集合,比如unicode中 A对应0041,汉字『我』对应 "6211"

unicode 是个很大的集合,几乎覆盖世界上所有的字符,现在的规模已经可以容纳100万个字符。

utf-8 是对 unicode 存储的实现方式

unicode 只定义字符对应的数字,但没有规定这些数字如何存储起来,比如像中文的『我』字存储时需要两个字节来表示,而英文字母A却只需要一个字节,有些其他的字符可能需要3-4个字节。

如果统一规定每个字符用3个或者4个字节来存储,那么每个英文字符都必然需要额外2到3个0,这对存储是很大的浪费。

如果每个字符按照实际需要的字节数来存储,计算机就分不清三个字节是表示三个字符还是一个字符。

utf-8 是对 unicode 编码存储的一种实现方式,同样的还有 utf-16, utf-32。

utf-8 是使用最广泛的编码方式,采用变长的编码方式,可以使用1-4个字节来表示一个字符; utf-16 用2个或4个字节,utf-32 用4个字节表示。编码规则如下:

对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母, UTF-8编码和ASCII码是相同的。

对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

python2 中的 str 和 unicode

python2 中有字符串类型有两种:byte string (str)unicode string (unicode)

>>> s = "美的"
>>> s
"xe7xbex8exe7x9ax84"
>>> s = u"美的"
>>> s
u"u7f8eu7684"
>>> s = "美的"
>>> s.decode("utf-8")
u"u7f8eu7684"

上面的输出中,第一个s的类型是 str,打印出来的内容是 utf-8 编码过的内容。第二个s的类型是 unicode,打印出来的两个双字节的数字分别表示了两个汉字『美的』。

encodedecode提供 str 和 unicode 这两种的类型的互相转化。

encode 把 unicode 转化成 str(byte string)

decode 把 str(byte string) 转化成 unicode

本质上,str是存放的字节序,有可能是 ascii, gbk, utf-8 等等中的任意一种,通过调用 decode 可以把他们转化成 unicode ,默认的 decode 编码是 ascii 。str中到底是用的哪一种编码,取决于它所在的场景,跟 locale ,文件编码等等都有关系。

文本文件、编辑器的处理
#!/usr/bin/env python
# -*- coding: GBK -*-

s = u"中文"
print repr(s)
print repr(s.encode("GBK"))

比如上面的文件enc.py,保存的时候选择文件编码是GBK,程序文件本质上也是文件,当我们使用某个外部的应用 打开它时(编辑器或者python解释器等),外部应用是不知道该文件的编码格式的,

这个时候有三种情况:

应用使用其默认的编码方式去解析,比如UTF-8或者ASCII;python解释器默认是ASCII,编辑器可以自己设置;

应用根据文件中的字节内容,自动检测编码方式;

文本文件告诉应用使用什么编码方式去解码;比如# -*- coding: GBK -*-告知解释器使用GBK来解码;

试验一下,把# -*- coding: GBK -*-删除后,执行python enc.py,输出:

   File "enc.py", line 4
 SyntaxError: Non-ASCII character "xd6" in file enc.py on line 4, but no encoding declared;

试着用vim打开该文件时,『中文』两个字就会显示成乱码,因为vim默认的文件编码方式被设置成UTF-8了。

#!/usr/bin/env python
# -*- coding: GBK -*-

s1 = u"中文"

print repr(s1)
print repr(s1.encode("GBK"))

s2 = "中文"

print repr(s2)
print repr(s2.decode("GBK"))

输出结果:

u"u4e2du6587"
"xd6xd0xcexc4"
"xd6xd0xcexc4"
u"u4e2du6587"

从这里可以看出来, s2中存放的是byte格式的从文件中读到的GBK编码的内容。

再看下面的这段代码,程序文件utf8_enc.py,保存成UTF-8编码的。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

s1 = u"中文"

print repr(s1)
print repr(s1.encode("GBK"))

s2 = "中文"

print repr(s2)
print repr(s2.decode("GBK"))

输出:

u"u4e2du6587"
"xd6xd0xcexc4"
"xe4xb8xadxe6x96x87"
Traceback (most recent call last):
  File "unicode_enc.py", line 12, in 
    print repr(s2.decode("GBK"))
UnicodeDecodeError: "gbk" codec can"t decode bytes in position 2-3: illegal multibyte sequence

这里同样可以知道,s2中存放的是文件保存的编码UTF-8的byte码。

References

http://www.rrn.dk/the-differe...
http://www.ruanyifeng.com/blo...
https://docs.python.org/2/how...
http://yergler.net/2012/bytes...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38215.html

相关文章

  • PythonUnicode

    摘要:最近使用处理一些网络相关的问题,被相关的一系列编码问题搞得一头雾水。与接下来是中对于字符串的处理。中的和在中,其类型规定了底层的数据结构,是位整数串,也即跟语言中的字符串类似。这些问题在中得到解决。 最近使用 Python 2 处理一些网络相关的问题,被 Unicode, String 相关的一系列编码问题搞得一头雾水。在这里整理一下相关的概念吧。 ASCII Unicode UTF8...

    Tangpj 评论0 收藏0
  • python中的编码问题

    摘要:在控制台执行命令中文,可以将解释为命令,中文,从而到到对象。中文以上的对象其实是,即字节码,若终端是编码的话,那么就是用的字节码。那么这里的是什么呢默认是,这正是错误为什么报无法用解码的原因中文将默认编码改为,即可。 问题 在平时工作中,遇到了这样的错误: UnicodeDecodeError: ascii codec cant decode byte 想必大家也都碰到过,很常见 。于...

    forsigner 评论0 收藏0
  • 关于解决Python乱码问题的终极解决方案 (TL;DR)

    摘要:关于解决乱码问题的终极解决方案有个特别好玩的现象,当我们为了编码头疼的时候,几乎搜索到所有的文章都会先发一通牢骚。另外,关于的乱码问题,又是一个新的较长篇章。 关于解决Python乱码问题的终极解决方案 (TL;DR) showImg(https://segmentfault.com/img/remote/1460000013229494?w=809&h=184); 有个特别好玩的现象...

    Lemon_95 评论0 收藏0
  • [零基础学Python]坑爹的字符编码

    摘要:所以,哪怕是初学者,都要了解并能够解决字符编码问题。在这个世界上,有好多不同的字符编码。目前最新的版本为,已收入超过十万个字符第十万个字符在年获采纳。涵盖的数据除了视觉上的字形编码方法标准的字符编码外,还包含了字符特性,如大小写字母。 字符编码,在编程中,是一个让学习者比较郁闷的东西,比如一个str,如果都是英文,好说多了。但恰恰不是如此,中文是我们不得不用的。所以,哪怕是初学者,都要...

    rozbo 评论0 收藏0
  • 编码-1

    摘要:关于的参考知乎上的一个回答传送门以我自己的理解就是首先得分清楚编码问题在不同的环境中,编码是不同的。但是如果换成的是知乎的话,则表示的是将这个汉字用编码的形式存放。 文章启发来源: cnblogs 阮一峰 知乎 字符编码方式 note from wiki: 从维基百科上得到的一些理解,一个字符的unicode编码是确定的,但是在传输过程中,由于不同系统平台的设计不一致,所以对uni...

    IamDLY 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<