23.字符串、字节串和字符编码
文章目录
- 前言
- 一、初始研究
- 二、开关、约定和编码
- 三、解剖输出
- 四、解剖代码
- 五、深度接触编码
- 总结
前言
要完成这个练习,需要下载一个languages.txt文件(百度、知乎也有资源)。这个文件里包含了一系列的人类语言。通过这个练习可以知道:
(1) 现代计算机如何存储人类语言,并进行显示或者处理。Python中将其称为字符串(string)。
(2) 把Python的字符串编码和解码为一个叫字节串(bytes)类型。
(3) 处理在字符串和字节处理中出现的错误。
(4) 如何阅读代码,明白看到的新东西。
一、初始研究
这里的代码需要languages.txt文件,编码格式是UTF-8。
import sys
script, encoding, error = sys.argv
def main(language_file, encoding, errors):
line = language_file.readline()
if line:
print_line(line, encoding, errors)
return main(language_file, encoding, errors)
def print_line(line, encoding, errors):
next_lang = line.strip()
raw_bytes = next_lang.encode(encoding, errors = errors)
cooked_string = raw_bytes.decode(encoding, errors = errors)
print(raw_bytes, "<===>", cooked_string)
languages = open("languages.txt", encoding = "utf-8")
main(languages, encoding, error)
在Window上键入Python就可以看到结果。
python ex23.py utf-8 strict
这些示例用了utf-8、utf-16以及big5编码来演示这种转换以及会遇到的错误类型。前面这些名称在Python中叫做"codec",但作为函数参数叫“encoding”(编码)。
二、开关、约定和编码
解释代码之前,论述一些计算机存储数据的基本知识。现代计算机极其复杂,简单讲,它们根本就是一个巨大的开关阵列。计算机用电来出发这些开关的开启或关闭。这些开关用1表示有电、开启、接通,用0表示没电、关闭、切断。并且称这些“1”和“0”为“位”(bit)。
计算机用这些1和0来编码出很大的数字,在小的一头,计算机会使用8位编码256个数字(0~255),编码就是一种大家都认同的转换标准。
使用“字节”(byte)表示一个8位(0和1)的序列,这是约定,这一约定定义了字节编码,还有一些约定用来表示更大的数字,会用到16位、32位、64位,甚至更长的序列。各种标准组织会统一一些争论,然后把它们作为编码实施起来,最终让他们实现开关的通断。
有了字节,确定了数字和字母之间的对应关系的约定,就可以存储和展现文本了。最常见的标准是美国信息交换标准代码(ASCII),这个标准把数字和字母相互对应:
首先,用二进制写出了90,然后获取了Z字母对应的数字,最后把数字转换成了字母。有了ASCII的约定,就能用8位(也就是1字节)编码一个字符,把字符串联在一起,组成一个单词。
ASCII有一个问题,它只能对英语和若干类似的语言进行编码。世界上的语言多种多样,用到的字符远超过256个。为了解决这个问题,有一群人发明了Unicode,它的意思是一种所有人类语言的“通用编码”(univesal encoding)。Unicode提供编码的方式和ASCII类似,用32位编码一个Unicode字符,这样对所有语言都够用了,32位意味着可以存储4294967295(2^32)个字符,可以装的下所有人类语言,多余的空间现在用它存储一些表情符号。
目前,采用了一种巧妙地方式,把大部分常用的字符用8位表示,如果需要编码更多的字符,就去使用更大的数(16位、32位),这是一种压缩编码的方式,也是一种编码约定,这一约定在Python中叫UTF-8(Unicode Transformation Format 8 Bits)。从编码Unicode字符带字节序列,再到为序列,再到一个通断的开关序列,都遵循了这一编码约定。
三、解剖输出
ex23.py脚本将 b‘ ’ (字节串)中的字节转换成了指定的UTF-8编码。左边是UTF-8的每一个字节的数字(十六进制),右边是真正输出的UTF-8字符。
四、解剖代码
在Python中,string是UTF-8编码的字符序列,是显示和处理文本的基础。bytes则是Python用来存储UTF-8字符串的原始字节序列。如下会话展示了字符串编码和字节串解码的操作。
# coding=utf-8
import sys
script, encoding, error = sys.argv
def main(language_file, encoding, errors): #关键代码才main的主函数开始,在结尾调用该函数
line = language_file.readline() # 读取文本的第一行
if line: # 基于这一真值来决定代码运行与否,只要readline()返回了文本内容,则为真,执行缩进的代码
print_line(line, encoding, errors) # 调用另一个函数执行打印操作
return main(language_file, encoding, errors) # 在main里面调用了以此main函数,其实就是一个循环
def print_line(line, encoding, errors): # 定义print_line函数,实际上是对languages.txt中的每一行进行编码
next_lang = line.strip() # 删除每段结尾的 n,该方法只能删除开头或是结尾的字符,不能删除中间部分的字符
raw_bytes = next_lang.encode(encoding, errors = errors) # 编译为原始字节
cooked_string = raw_bytes.decode(encoding, errors = errors) # 解码
print(raw_bytes, "<===>", cooked_string) # 打印二者出来
languages = open("languages.txt", encoding = "utf-8") # 打开languages.txt
main(languages, encoding, error) # 执行main函数,带了需要的所有参数。开始循环
五、深度接触编码
总结
以上内容介绍了Python的字符串、字节串和字符编码,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。



