字符编码

 

首先,有几种字符集:ASCII、Unicode、UTF-8。同样的一个字符,在其所能够出现的所有字符集中,都具有一个编码

ASCII字符集是最小的,对应的大致是英文需要使用的各种字符(大致就是你键盘上能看见的那些字符),以及\n、\b、\a这样的一些基本的在计算机中起特殊作用的字符。ASCII字符的编码,以及存储在内存中时,空间占用为1字节。

Unicode字符集就还包含了其他各种语言所需使用的字符,当然也包括中文(以及日、韩等)所需使用的汉字。空间占用:一般2字节,很生僻的要4字节。所有的ASCII字符都是Unicode字符,它们的ASCII和Unicode编码也是相同的。但也存在许多非ASCII的Unicode字符。(为方便,下文中,前者一律称为“ASCII字符”,后者则称“Unicode字符”。但注意,“Unicode编码”一词也适用于ASCII字符。)

UTF-8字符集中的字符与Unicode字符相同,但编码方式不一样。UTF-8字符集中字符所占内存空间不固定,ASCII字符只占1字节(与ASCII编码时情况相同),而汉字(Unicode字符)一般占3字节。设计的初衷是,如果一篇文章中大多数字符都是ASCII字符(但也有少数Unicode字符),按UTF-8存储就可以省空间,并且不会“坏掉”Unicode字符了。

 

Python的字符串

 

Python 3中,字符串以Unicode编码。

 

字符的基础知识

 

ord()和chr()

 

ord()用来获得字符的Unicode编码,chr()用来获得相应Unicode编码的字符。

 

\u

 

可以用转义序列\u####(#表数字)来指定字符,其中####为该字符的16进制Unicode编码。注意一定要4个数字,因为它表示一个2字节Unicode字符(164 = 22)。

 

补充:\x、\U

 

在Python中,除了用\u####来指定Unicode字符以外,还存在一种转义序列\x##,用来指定一个字节(byte),或者说一个ASCII或扩展ASCII字符。其中##同样是16进制,且表示2个数字【因为它表示1字节的整数(162 = 21)】。如果编码为##的ASCII(或扩展ASCII)字符存在,则显示为相应的ASCII(或扩展ASCII)字符。我们马上就会遇见\x的使用。

Python还支持4字节的Unicode字符,它们用\U########(\U后加8位16进制数)表示。

 

str与bytes

 

bytes也是一种Python数据类型,用于存储一系列的字节

 

表示

 

用b' '(或B' '、b" "、B" ")表示一个bytes类型的数据,如:b'ABC'。这与字符串的表示类似。

 

str转bytes:方法encode()

 

str有方法encode(),可以把自己转换(编码)为bytes。encode()还要求提供一个参数:编码方式,即使用哪套编码。常见的有两种:'ascii'和'utf-8'。

 

可能遇见的错误:将Unicode字符编码为ASCII。这样是会报错的(UnicodeEncodeError)。

 

bytes转str:方法decode()

 

bytes也有方法decode(),将自己转换(解码)为str。decode()同样也要求提供一个参数,与encode()同理。

 

可能遇见的错误:bytes中包含无法解码的字节。这样是会报错的(UnicodeDecodeError)。(但此时可以再传入一个参数errors='ignore'来忽略错误的字节。)

 

len()

 

对于str,函数len()计算其字符数;对于bytes,函数len()计算其字节数。

 

最后

 

如果要多次进行str/bytes间的转化,为避免乱码,应坚持使用UTF-8。

 

许多Python代码——在含有Unicode字符时——都会在开始出加入下面的2行注释:

 



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


 

这是为了防止Unicode字符被错误处理(第一行给Linux / OS X的,我就不说了;第二行告诉Python按UTF-8处理源代码)。不过注意,光是这样还是不够的,还需要在文本编辑器中指定使用UTF-8。个人觉得,假若你使用UTF-8编码,那么原因应该是:1)你的代码中有Unicode字符(对于我国人来说,一般就是中文字符);2)中文字符只占你的代码的很小一部分,其余的都是ASCII字符(英文字符)。

从逻辑上讲,应该是这样:先是出于这两条原因你决定使用UTF-8,然后再是在代码的文本编辑器里指定使用UTF-8导致你的Python源代码以UTF-8的形式存储在系统中,这样(在有Unicode字符的前提下)内存就省了。但电脑中的任何一个文件其实都是一系列的字节序列(每个字节本质上是整数0~255),文本文件本质上也是将其中的文字按其字符编码保存的——但问题是编码方式多种多样,因此当文本文件被读取(这里是.py被Python解释器读取)时,那些字节怎么解读就成为了一个问题。Python解释器默认它读取到的.py文件中的文本按Unicode编码,但你使用的不是Unicode而是UTF-8,所以你就需要再在文件顶端加上 # -*- coding: utf-8 -*- 这样一句声明,使得Python在读到你的源代码(所对应的字节序列)时知道它读取的是UTF-8。切记,你现在正在阅读的这些文字,在计算机世界中其实都是“表象”;本质上,它们只是被计算机,按照人为制定的字符编码规则,被显示成了相应的文字形状的东西而已!

 

格式化

 

Python有3种方法对字符串进行格式化:%、format()和f字符串。略。