最近用到Python2.7处理中文遇到了很多坑,查阅了一些资料后终于基本弄清楚了基本编码问题,写下此文作为总结。最好的学习资料是维基百科,不过百科里写的比较啰嗦,本文精简地梳理了这些核心概念。看完本文后,对某个概念仍然不清楚可以继续阅读对应百科词条。
ASCII和Unicode
我们知道计算机世界中地一切都是0和1,所有符号在计算机中都会被处理成二进制数据。英文字母、汉字,以及其他符号,都不能直接被计算机识别。因此,作为约定,我们需要某种字符编码,将字符和数字一一对应,使得计算机可以认出某个符号。
ASCII就是一种字符编码规范,它将因为大小写字母、数字,和其他一些常用符号,跟数字0到127一一对应。计算机的一个byte字节能表示0到255,故只需要一个字节即可表示ASCII范围内的一个符号。
ASCII是美国的标准,只能表示英文,世界上其他国家的文字都没有包含在内。Unicode应运而生。很长一段时间里,我都有一个错误的观念,即Unicode字符占两个字节,然而查阅资料后我看到Unicode大部分字符占2个字节,然而最多的字符能占到6个字节。当然包括中文在内的大部分常用字符占2个字节。
Utf-8
很长一段时间我都觉得Unicode和Utf-8是一回事儿,查阅资料后才发现Utf-8是一种对Unicode的编码方式。Unicode可以理解为将符号跟数字的一一对应,而Utf-8是把数字再一次编码为字节。除了Utf-8之外,还有Utf-16、Utf-32都是Unicode的具体编码方式。
Utf-8的特点是可以兼容ASCII,将ASCII范围内的字符编码成一个字节,换句话说,用Utf-8的解码方式是可以打开ASCII文件的,而一个只包含英文的文件,编码成ASCII和Utf-8,其结果是一样的。而对于中文等其他他部分常用符号,utf-8会编码成3个字节。具体的编码方式建议大家查阅其他资料。
Python2编码问题
如不搞明白一些基本概念,python2使用中文会遇到各种奇葩问题。
在文件开头加上# -*- coding: utf-8 -*的作用是,将本文件处理为utf-8。
Python2的字符串默认是ASCII编码,在字符串前加上u(如u‘中国’),这样会把字符串处理成Unicode。如前文所讲,还需要一个步骤,将Unicode转化为字节,这就涉及到encode和decode两个方法。decode是把特定编码方式的字符(如Unicode)转化为字节,encode是把某种编码方式的字节转化为字符。