1.1. 字符编码
1.1.1. 字符编码的作用
计算机只认识0和1组成的二进制序列,因此任何文件中的内容(比如"hello neuedu","你好,东软睿道"这些字符串)要想被计算机识别或者想存储在计算机上都需要转换为二进制序列。那么字符与二进制序列怎么进行相互转换呢?于是人们尝试建立一个表格来存储一个字符与一个二进制序列的对应关系。
- 编码 将字符转换为对应的二进制序列的过程叫做字符编码
- 解码 将二进制序列转换为对应的字符的过程叫做字符解码
1.2. 字符编码的简单发展历史
1.2.1. ASCII码诞生
最早建立这个字符与十进制数字对应的关系的是美国,这张表被称为ASCII码(American Standard Code for Information Interface, 美国标准信息交换代码)。ASCII码是基于拉丁字母的一套电脑编程系统,主要用于显示现代英语和其他西欧语言。它被设计为用1个字节来表示一个字符,所以ASCII码表最多只能表示2**8=256个字符。实际上ASCII码表中只有128个字符,剩余的128个字符是预留扩展用的。
1.2.2. GBK等各国编码诞生
随着计算机的普及和发展,很过国家都开始使用计算机。大家发现ASCII码预留的128个位置根本无法存储自己国家的文字和字符,因此各个国家开始制定各自的字符编码表,其中中国的的字符编码表有GB2312和GBK。
1.2.3. Unicode诞生(万国码)
后来随着世界互联网的形成和发展,各国的人们开始有了互相交流的需要。但是这个时候就存在一个问题,每个国家所使用的字符编码表都是不同的。这个时候,人们希望有一个世界统一的字符编码表来存放所有国家所使用的文字和符号,这就是Unicode。Unicode又被称为 统一码、万国码、单一码,它是为了解决传统的字符编码方案的局限性而产生的,它为每种语言中的每个字符设定了统一并且为之一的二进制编码。Unicode规定所有的字符和符号最少由2个字节(16位)来表示,所以Unicode码可以表示的最少字符个数为2**16=65536。
1.2.4. UTF-8诞生
为什么已经有了Unicode还要UTF-8呢?因为美国人不乐意了,由于当时存储设备是非常昂贵的,而Unicode中规定所有字符最少要由2个字节表示。美国人认为像原来ASCII码中的字符用1个字节就可以了,因此决定创建一个新的字符编码来节省存储空间。UTF-8是对Unicode编码的压缩和优化,它不在要求最少使用2个字节,而是将所有字符和符号进行分类:
- ascii码中的内容用1个字节保存
- 欧洲的字符用2个字节保存
- 东亚的字符用3个字节保存
- ...
UTF-8是目前最常用,也是被推荐使用的字符编码。
1.3. 字符串和字节序列的转换
1.3.1. 字符串转字节序列
bytes = '张三'.encode() print(bytes) print(type(bytes)) bytes = '张三'.encode('utf-8') print(bytes) print(type(bytes)) bytes = '张三'.encode('gbk') print(bytes) print(type(bytes))
输出
b'\xe5\xbc\xa0\xe4\xb8\x89' <class 'bytes'> b'\xe5\xbc\xa0\xe4\xb8\x89' <class 'bytes'> b'\xd5\xc5\xc8\xfd' <class 'bytes'>
encode默认按utf-8编码
1.3.2. 字节序列转字符串
bytes = b'\xe5\xbc\xa0\xe4\xb8\x89' msg1 = bytes.decode() print(msg1) print(type(msg1)) msg1 = bytes.decode('utf-8') print(msg1) print(type(msg1)) msg1 = bytes.decode('gbk') print(msg1) print(type(msg1))
输出
张三 <class 'str'> 张三 <class 'str'> 寮犱笁 <class 'str'>
1.4. 文件的概念和作用
- 计算机的 文件,就是存储在硬盘上的 数据
1.5. 文件的存储方式
- 在计算机中,文件是以 二进制 的方式保存在磁盘上的
1.5.1. 文本文件和二进制文件
- 文本文件(字符串)
- 可以使用 文本编辑软件 查看
- 本质上还是二进制文件
- 例如:python 的源程序
- 二进制文件
- 保存的内容 不是给人直接阅读的,而是 提供给其他软件使用的
- 例如:图片文件、音频文件、视频文件等等
- 二进制文件不能使用 文本编辑软件 查看
1.6. 文件的基本操作
1.6.1. 操作文件的套路
在 计算机 中要操作文件的套路非常固定,一共包含三个步骤:
- 打开文件
- 读、写文件
- 读 将文件内容读入内存
- 写 将内存内容写入文件
- 关闭文件
1.6.2. 操作文件的函数/方法
- 在
Python
中要操作文件需要记住 1 个函数和 3 个方法
序号 | 函数/方法 | 说明 |
01 | open | 打开文件,并且返回文件操作对象 |
02 | read | 将文件内容读取到内存 |
03 | write | 将指定内容写入文件 |
04 | close | 关闭文件 |
-
open
函数负责打开文件,并且返回文件对象
-
open
函数的第一个参数是要打开的文件名(文件名区分大小写)
-
- 如果文件 存在,返回 文件操作对象
- 如果文件 不存在,会 抛出异常
-
read
方法可以一次性 读入 并 返回 文件的 所有内容 -
close
方法负责关闭文件
-
- 如果 忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问 新建一个demo.txt文件,输入neuedu,放到和readfile.py同级目录下
- 1.最开始,我们用某个编辑软件(记事本程序),编辑了"东软睿道"四个字符,按
utf-8
编码方式保存到磁盘上,此处放生了编码过程(字符串--->字节)。 2.接下来我们通过上面的python代码,打开(open)文件,此时将存储在文件中的字符串(字节,二进制),读取到变量中(内存中),转换成字符串。这会发生一个解码过程(字节--->字符串)。Python默认是按照什么编码方式解码的呢,输出信息给出了答案
<_io.TextIOWrapper name='demo2.txt' mode='r' encoding='cp936'>
- open函数返回的是TextIOWrapper类型的文件对象,cp936是默认的文本编码格式(gb2312) 说明文件打开时默认按gb2312编码方式进行解码。编码和解码的方式不同,故而发生乱码。解决办法有2个: 1.记事本编辑完保存时,按'gb2312'方式保存到磁盘(ANSI)2.文件打开时指定编码方式为utf-8:
read
/write
/close
三个方法都需要通过文件对象来调用1.7. 文件指针文件指针 标记 从哪个位置开始读取数据
- open函数返回的是TextIOWrapper类型的文件对象,cp936是默认的文本编码格式(gb2312) 说明文件打开时默认按gb2312编码方式进行解码。编码和解码的方式不同,故而发生乱码。解决办法有2个: 1.记事本编辑完保存时,按'gb2312'方式保存到磁盘(ANSI)2.文件打开时指定编码方式为utf-8:
- 第一次打开 文件时,通常 文件指针会指向文件的开始位置
- 当执行了 read 方法后,文件指针 会移动到 读取内容的末尾
- 思考 如果执行了一次 read 方法,读取了所有内容,那么再次调用 read 方法,还能够获得到内容吗?
答案 不能 第一次读取之后,文件指针移动到了文件末尾,再次调用不会读取到任何的内容
控制文件指针移动 方法:f.seek(offset,whence) offset代表文件指针的偏移量,单位是字节bytes whence代表参照物,有三个取值 (1)0:参照文件的开头 (2)1:参照当前文件指针所在的位置 (3)2:参照文件末尾
PS:快速移动到文件末尾f.seek(0,2) 强调:其中whence=1和whence=2只能在b 模式下使用 f.tell()函数可以得到当前文件指针的位置
- 思考 如果执行了一次 read 方法,读取了所有内容,那么再次调用 read 方法,还能够获得到内容吗?