python 字符编码

来源:互联网 发布:写私密日记的软件 编辑:程序博客网 时间:2024/06/01 22:15

python的字符编码如果不弄明白,早晚会坑你一把的。python2 和python3的升级之一就是字符编码。python2的默认字符编码是ASCII ,而python3 的默认字符编码是unicode。

编码的起源

ASCII码是最早的字符编码,python诞生的时候没有考虑过其他国家也会使用计算机,使用python,于是在最初设计的时候就用ASCII作为默认的编码。ASCII码是8个字节,最多只能表示256个字符,肯定不够用呀,或者说只够老美用的,那其他国家怎么办。于是每个国家就自己整了一个对照表,比如我国就是gb2312(后来是gbk,汉子多了一些)。虽然每个国家都有自己的对照表,但是在自己的国家里面玩玩还可,出去可就不行了。就像语言一样,你去哪都说汉语,外国人听不懂呀,还搞毛线呀。必须有一个统一的编码出现才行,事后unicode就闪亮登场了。
unicode编码有各个国家编码的对照规则,所以能够显示各个国家的语言。这样夸国之间的编码问题就解决了。但是由于各国编码所占的字节不同,unicode编码在融合各国国家编码之后就变成了2个字节表示一个字符,(有的不常用的是4个字节)。这样就带来了两个问题

  • 原来老美的英文文档存储空间直接扩大了一倍
  • 当资源在网络传输中,消耗的带宽增加一倍

为了解决上面的问题,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

python 2编码

python2 的默认编码是ascii,ascii不能表示中文。如果表示中文需要转换成支持中文的编码(utf-8,unicode,gbk)
注意:Unicode是编码相互转换的中介,因为它包含编码的转换关系。

指定文件编码 #-- coding:utf-8 --

#!/usr/bin/env pythons = "你好"print s结果报错:SyntaxError: Non-ASCII character '\xe4' in file /home/liubo/docker-publish/publish_django/编码.py on line 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

ascii编码是不支持中文的,需要指定文件编码

#!/usr/bin/env python#-- coding:utf-8 --s = "你好"print s结果:    你好

编码转换:

  • Unicode是中间编码,如ascii转换成utf-8,需 ascii–>unicode–>utf-8
  • decode 解码,是其他编码转换成unicode
  • encode 编码,是unicode转换成其他编码
#!/usr/bin/env python#-- coding:utf-8 --s = "你好"print sprint type(s)s_uni = s.decode(encoding="utf-8")print s_uniprint type(s_uni)s_gbk = s_uni.encode(encoding="gbk")print s_gbkprint type(s_gbk)s_utf8 = s_uni.encode(encoding="utf-8")print s_utf8print type(s_utf8)

结果

你好<type 'str'>你好<type 'unicode'>���<type 'str'>你好<type 'str'>

python3 编码

python3中编码有两种类型,一种是str,另外一种是bytes.

  • str 就是unicode
  • bytes是其他类型(utf-8,ascii,gbk等)
  • 在内存中是unicode,在硬盘上或者网络传输时是bytes
s = "你好"print (s)print (type(s))s_gbk = s.encode(encoding="gbk")print (s_gbk)print (type(s_gbk))s_utf8 = s.encode(encoding='utf-8')print (s_utf8)print (type(s_utf8))

结果

你好<class 'str'>b'\xc4\xe3\xba\xc3'<class 'bytes'>b'\xe4\xbd\xa0\xe5\xa5\xbd'<class 'bytes'>

总结:

编码尽量用utf-8格式,已经逐渐成为一种标准。
如果遇到乱码,从文件编码,解释器编码,终端编码,系统编码来排查问题。