字符编码
1、储备知识
运行python程序的三个步骤:python.py 1、先启动python解释器 2、解释器会将文本文件a.py内容由硬盘读入内存 3、解释器会解释执行刚刚读入内存的内容,识别python语法
2、什么是字符编码
人类的字符 ----- 编码 -----> 数字 人类的字符 <----- 解码 ----- 数字 编码与解码的过程必须参照字符编码表
3、为何要学习字符编码
为了解决运行python程序三个阶段中2、3阶段有可能出现的乱码问题
4、字符编码表发展史
一家独大: ASCII:只能识别英文字符 8bit 对应一个英文字符 1byte = 8bit (byte:字节 bit:(二进制)位,比特) 天下大乱 GBK:能识别汉子与英文 用2Bytes对应一个字符 Shift-JIS:日文与英文 Euc -KR:韩文与英文 英文字符----->内存:ASCII格式的二进制----->硬盘:ASCII格式的二进制 中文字符、英文字符----->内存:gbk格式的二进制----->硬盘:gbk格式的二进制 日文字符、英文字符----->内存:shift-JIS格式的二进制----->硬盘:shift-JIS格式的二进制 万国字符----->内存:unicode格式的二进制----->硬盘:utf-8格式的二进制 分久必合 unicode:1、万国字符 2、兼容老的字符编码表
5、结论
如何保证不乱码
1、编码与解码必须参照同一张字符编码表
文件操作
文件处理
1、什么是文件
文件时操作系统提供给用户或者应用程序操作硬盘的一种机制
python中文件是对象
Linux文件:一切设备都可以看成是文件
文件的作用:把一些数据以文件的形式存储起来,文件由文件系统进行管理,当程序下一次执行的时候,通过文件系统快速找到对应的文件,而找到对应的数据,省时省力。
2、为何要用文件
读写文件 ---> 存取硬盘
应用程序: open()
操作系统: 打开文件
计算机硬件: 硬盘空间
3、如何用文件
打开文件的两种方式
方式一 open
# encoding指定字符编码表 f = open(r'aa.txt',mode ='rt',encoding='utf-8') # f的值 ---> 文件句柄,文件对象 res = f.read() print(res) f.close() # 回收操作系统的资源
方式二 with open
with open(r'aa.txt',mode = 'rt',encoding = 'utf-8') as f: res = f.read() print(res)
读写
要了解文件读写模式,需要了解几种模式的区别,以及对应指针 1、控制读写操作模式 r: 读取文件,文件存在的时候,文件指针调到文件开头,若文件不存在则会报错 ----->默认 w:写入文件,在文件存在的时候会清空文件,文件指针调到文件开头,若文件不存在则会先创建再写入,会覆盖源文件 a:写入文件,在文件存在的时候不会清空文件,文件指针调到文件末尾,若文件不存在则会先创建再写入,但不会覆盖源文件,而是追加在文件末尾 2、控制读写内容模式 t:读写都是文本格式,即读写都是字符串 ----->默认 b:读写都是bytes格式,bytes等同于二进制 强调:如果是 t 模式,一定记住加上encoding = '编码格式' 如果是 b 模式。一定记住别加encoding = '编码格式' 3、 + r+:可读可写,文件不存在也会报错,写操作是会覆盖 w+:可读,可写,文件不存在先创建,会覆盖 a+:可读,可写,文件不存在先创建,不会覆盖,追加在末尾 注意:这里的覆盖是指每次重新打开文件进行操作是覆盖原来的,如果实在打开文件中则不会覆盖
关闭文件
文件关闭的原因: *将写缓存同步到磁盘 *Linux系统中每一个进程打开文件的个数是有限的,如果打开文件数到了系统限制,则会打开失败。
文件处理的打开模式
1、控制读写操作的模式
r:只读 w:只写 a:只追加
2、控制文件读写内容的模式
t:读写的内容都是字符串类型 特点:1、只适用于文本文件 2、必须要指定encoding参数 b:控制读写的内存都是bytes类型 特点: 2、一定不要指定encoding参数
r:如果文件不存在则报错,文件存在则将文件指针跳到整个文件的开头 with open(r'b.txt','rt',encoding = 'utf-8') as f: res = f.read()
w:如果文件不存在则创建空文档,如果文件存在则清空,文件指针跳到文件开头 打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面 with open(r'b.txt',mode = 'wt',encoding = 'utf-8') as f: f.write('123 ') f.write('123 ') f.write('123 ')
a:如果文件不存在则创建文件,如果文件存在则追加写,文件指针调到文件末尾 打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面 with open(r'b.txt',mode = 'at',encoding = 'utf-8') as f: f.write('123 ') f.write('123 ') f.write('123 '
3、读写模式
""" r+t w+t a+t """ f = open(r'b.txt',mode = 'r+t',encoding = 'utf-8') print(f.readable()) # True print(f.writable()) # True f.close()
""" b模式 一定不要指定encoding参数 """ with open('b.txt',mode = 'rb',encoding = 'utf-8') as f: pass ValueError: binary mode doesn't take an encoding argument with open('b.txt',mode = 'rb') as f: res = f.read() print(type(res)) # <class 'bytes'> print(res) # b'123 123 123 ' print(res.decode('utf-8')) >>>: 123 123 123
4、文件操作方法
文件的读取
read(size) 作用:读取文件(读取size个字节,默认读取全部) # 只有t模式下的read(n)代表的是字符个数,除此以外都是字节个数 readlines(size) 作用:读取文件返回每一行所组成的列表(读取size行,默认读取全部) readline() 作用:读取一行 with open(r'a.txt',mode='rt',encoding = 'utf-8') as f: res = f.read() print(res) print('==========') res = f.read() print(res) with open(r'a.txt',mode='rt',encoding = 'utf-8') as f: print(f.readline()) print(f.readline()) with open(r'a.txt',mode='rt',encoding = 'utf-8') as f: print(f.readlines()) # ['123 ', '123 ', '123 ', 'egon ', 'egon 123 ', '123'] # a.txt内容:hello你好啊 with open(r'a.txt',mode='rt',encoding = 'utf-8') as f: print(f.read(6)) # hello你 with open(r'a.txt',mode='rb') as f: print(f.read(6)) # b'helloxe4' # 截断文件内容 with open(r'a.txt',mode='a',encoding = 'utf-8') as f: f.truncate(6) # hello�
文件的写入
with open(r'a.txt',mode='wt',encoding = 'utf-8') as f: lines = ['aaa ','bbb ','ccc '] # for line in lines: # f.write(line) f.writelines(lines) with open(r'a.txt',mode='wt',encoding = 'utf-8') as f: f.write('hello') # f.flush() # 降低效率
5、控制文件指针移动
f.seek(移动的字节个数,模式) 模式有三种: 0:永远参照文件开头 1:参照当前所在的位置 2:永远参照文件末尾 注意: 只有0模式可以在 t 下使用 1 和 2 只能在 b 模式下使用
# a.txt内容:hello你好啊with open(r'a.txt',mode='rt',encoding = 'utf-8') as f: f.seek(3,0) print(f.tell()) # 距离文件开头有多少个字节 with open(r'a.txt',mode='rb') as f: f.seek(3,1) f.seek(5,1) print(f.tell()) # 8 res = f.read() print(res.decode('utf-8')) # 好啊 with open(r'a.txt',mode='rb') as f: f.seek(-3,2) print(f.tell()) # 11 res = f.read() print(res.decode('utf-8')) # 啊 # 指针跳到文件末尾 with open(r'a.txt',mode='rb') as f: f.seek(0,2)
指针跳到文件末尾的两种方式
"""方式一""" with open(r'a.txt',mode='rb') as f: f.seek(0,2) """ 方式二 a:如果文件不存在则创建文件,如果文件存在则追加写,文件指针调到文件末尾 打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面 """ with open(r'a.txt',mode='at',encoding='utf-8') as f: f.write('123 ')
6、文件的修改
文件的数据是存放于硬盘之上的,因而只存在覆盖,不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说法有两种实现方式 ;
方式一
1、以r模式打开源文件,将源文件内容全部读入内存 2、然后在内存中修改完毕 3、以w模式打开源文件,将修改后的内容写入源文件 耗费内存不耗费硬盘
with open('a.txt',mode = 'rt',encoding = 'utf-8') as src_f: data = src_f.read() res = data.replace('liu','egno') with open('a.txt',mode = 'wt',encoding = 'utf-8') as dst_f: dst_f.write(res)
方式二
1、以r模式打开源文件,然后以w模式打开一个临时文件 2、从源文件中读一行到内存中,修改完毕后直接写入临时文件,往复循环,直到操作完所有行 3、删除源文件,将临时文件名改名为源文件 耗费硬盘不耗费内存
import os with open('b.txt',mode = 'rt',encoding = 'utf-8') as src_f, open('.b.txt.sap',mode = 'wt',encoding = 'utf-8') as dst_f: for line in src_f: dst_f.write(line.replace('egno','liu')) os.remove('b.txt') os.rename('.b.txt.swp','b.txt')