3.5 Python文件与异常#
学习目标#
- 知道什么是文件
- 掌握文件的读写基本操作
- 知道with open()语句的特点
- 掌握Python异常处理方式
- 学会使用debug断点调试
一、文件的概念#
学习目标#
- 理解文件的相关概述
- 理解文件的作用
1 什么是文件#
内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索,引入了==“文件”==的概念。
一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。

2 思考:文件操作包含哪些内容呢?#
在日常操作中,我们对文件的主要操作:创建文件、打开文件、文件读写、文件备份等等

3 文件操作的作用#
文件操作的作用就是==把一些内容(数据)存储存放起来==,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力。
小结#
Q1: 文件操作包括哪些内容?
- 打开文件
- 读写操作
- 关闭文件
二、文件的基本操作#
学习目标#
- 掌握绝对路径和相对路径的写法
- 掌握文件的读取相关操作
- 掌握文件的写入相关操作
1 open函数打开文件#
在Python,使用open()函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:
f = open(name, mode)
注:返回的结果是一个file文件对象(后续会学习,只需要记住,后续方法都是f.方法())
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。 mode:设置打开文件的模式(访问模式):只读r、写入w、追加a等。
r模式:代表以只读模式打开一个已存在的文件,后续我们对这个文件只能进行读取操作。如果文件不存在,则直接报错。另外,r模式在打开文件时,会将光标放在文件的第一行(开始位置)。 w模式:代表以只写模式打开一个文件,文件不存在,则自动创建该文件。w模式主要是针对文件写入而定义的模式。但是,要特别注意,w模式在写入时,光标也是置于第一行同时还会清空原有文件内容。 a模式:代表以追加模式打开一个文件,文件不存在,则自动创建该文件。a模式主要也是针对文件写入而定义模式。但是和w模式有所不同,a模式不会清空文件的原有内容,而是在文件的尾部追加内容。 文件路径:① 绝对路径 ② 相对路径 ① 绝对路径:绝对路径表示绝对概念,一般都是从盘符开始,然后一级一级向下查找(不能越级),直到找到我们要访问的文件即可。 比如访问C盘路径下的Python文件夹下面的python.txt文件,其完整路径:
Windows
C:\Python\python.txt
Linux
/usr/local/nginx/conf/nginx.conf
绝对路径一般路径固定了,文件就不能进行移动,另外在迁移过程中会比较麻烦。 ② 相对路径:相对路径表示相对概念,不需要从盘符开始,首先需要找到一个参考点(就是Python文件本身) 同级关系:我们要访问的文件与Python代码处于同一个目录,平行关系,同级关系的访问可以使用
./文件名称或者直接写文件名称即可 上级关系:如果我们要访问的文件在当前Python代码的上一级目录,则我们可以通过../来访问上一级路径(如果是多级,也可以通过../../../去一层一层向上访问 下级关系:如果我们要访问的文件在与Python代码同级的某个文件夹中,则我们可以通过文件夹名称/来访问某个目录下的文件
2 入门级案例#
# 1、打开文件
f = open('python.txt', 'w')
# 2、写入内容
f.write('人生苦短,我学Python!')
# 3、关闭文件
f.close()
强调一下:中文乱码问题,默认情况下,计算机常用编码ASCII、GBK、UTF-8
3 解决写入中文乱码问题#
# 1、打开文件
f = open('python.txt', 'w', encoding='utf-8')
# 2、写入内容
f.write('人生苦短,我学Python!')
# 3、关闭文件
f.close()
4 文件的读取操作#
read(size)方法:主要用于文本类型或者二进制文件(图片、音频、视频...)数据的读取
size表示要从文件中读取的数据的长度(单位是字符/字节),如果没有传入size,那么就表示读取文件中所有的数据。
f.read() # 读取文件的所有内容
f.read(1024) # 读取1024个字符长度文件内容,字母或数字
# 1、打开文件
f = open('python.txt', 'r', encoding='utf-8')
# 2、使用read()方法读取文件所有内容
contents = f.read()
print(contents)
# 3、关闭文件
f.close()
readlines()方法:主要用于文本类型数据的读取
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
# 1、打开文件
f = open('python.txt', 'r', encoding='utf-8')
# 2、读取文件
lines = f.readlines()
for line in lines:
print(line, end='')
# 3、关闭文件
f.close()
readline()方法:一次读取一行内容,每运行一次readline()函数,其就会将文件的指针向下移动一行
f = open('python.txt’)
while True:
# 读取一行内容
content = file.readline()
# 判断是否读取到内容
if not content:
break
# 如果读取到内容,则输出
print(content)
# 关闭文件
f.close()
5 聊聊文件操作的mode模式#
| 模式 | 描述 |
|---|---|
| r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
| rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
| r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
| rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
| w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
| wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
| w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
| wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
| a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
| ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
| a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
| ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
虽然mode文件操作模式很多,但是我们只需要记住3个字符即可。r、w、a r+、w+、a+,代加号,功能全,既能读,又能写(区别在于指针到底指向不同) rb、wb、ab,代b的字符,代表以二进制的形式对其进行操作,适合读取文本或二进制格式文件,如图片、音频、视频等格式 rb+、wb+、ab+,代加号,功能全,既能读,又能写(区别在于指针到底指向不同)
小结#
Q1: 文件操作相关的函数有哪些?
- 打开文件: open()
- 读取数据: read(), readline(), readlines()
- 关闭文件: close()
三、with-open语句#
它主要是针对于 文件操作的, 即: 你再也不用手动 close()释放资源了, 该语句会在 语句体执行完毕后, 自动释放资源.
1 with-open格式:#
with open('路径', '模式', '码表') as 别名, open('路径', '模式', '码表') as 别名: 语句体
2 with-open特点:#
语句体执行结束后, with后边定义的变量, 会自动被释放.
3 with-open案例:#
# 1. 打开 数据源 和 目的地文件.
with open('./data/a.txt', 'rb') as src_f, open('./data/b.txt', 'wb') as dest_f:
# 2. 具体的 拷贝动作.
# 2.1 循环拷贝.
while True:
# 2.2 一次读取8192个字节.
data = src_f.read(8192)
# 2.3 读完了, 就不读了.
if len(data) <= 0:
# if data == '':
break
# 2.4 走到这里, 说明读到了, 把读取到的数据写出到目的地文件.
dest_f.write(data)
四、文件综合案例#
1 案例需求#
反转文件内容.按行读取文件内容, 对每行的内容进行反转后, 写到另1个文件中. 例如:数据源文件: a.txt
数据源文件: a.txt
好好学习,
天天向上.
abc123!@#
目的地文件: b.txt
,习学好好
.上向天天
#@!321cba
2 实现思路#
① 读取两个文件a.txt,并且将读取到的文件存储到一个列表中 ② 遍历文件行中所有的内容,去除行末换行符,使用切片方式翻转内容 ③ 将翻转后的内容加载到一个新的列表中 ④将新列表的中的内容以文件的方式写到本地磁盘b.txt
3 代码实现#
# 1. 定义源文件路径和目标文件路径
source_file = "a.txt"
destination_file = "b.txt"
# 2. 打开源文件以读取模式 ('r')
with open(source_file, "r", encoding="utf-8") as src_file:
# 3. 读取源文件的所有行
lines = src_file.readlines()
# 4. 初始化一个列表用于存储反转后的行
reversed_lines = []
# 5. 遍历每行内容
for line in lines:
# 6. 去除行末的换行符
stripped_line = line.rstrip('\n')
# 7. 反转行内容
reversed_line = stripped_line[::-1]
# 8. 将反转后的行添加到列表中,并添加换行符
reversed_lines.append(reversed_line + '\n')
# 9. 打开目标文件以写入模式 ('w')
with open(destination_file, "w", encoding="utf-8") as dest_file:
# 10. 将反转后的行写入目标文件
dest_file.writelines(reversed_lines)
# 11. 打印操作完成的消息
print(f"文件内容已反转并保存到 {destination_file}")
4 巩固练习#
拷贝文件并改名.例如: 把 a.py文件 拷贝到 a[备份].txt 文件中
# 1. 定义源文件路径
source_file = "a.py"
# 2. 通过字符串切片和拼接方式定义目标文件路径
base_name = source_file[:-3] # 去掉文件扩展名
destination_file = base_name + "[备份].txt"
# 3. 打开源文件以读取模式 ('r')
with open(source_file, "r", encoding="utf-8") as src_file:
# 4. 读取源文件的所有内容
content = src_file.read()
# 5. 打开目标文件以写入模式 ('w')
with open(destination_file, "w", encoding="utf-8") as dest_file:
# 6. 将源文件的内容写入目标文件
dest_file.write(content)
# 7. 打印操作完成的消息
print(f"文件 {source_file} 已拷贝并保存为 {destination_file}")
五、Python异常#
学习目标#
- 掌握捕获异常的格式
1 什么是异常#
当检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。
2 异常演示#
# 除数为0
# print(10/0)
# 文件读取异常
f = open('python.txt', 'r')
content = f.readlines()
print(content)
3 异常捕获#
基本语法:
try:
可能发生错误的代码
except:
如果出现异常执行的代码
try...except主要用于捕获代码运行时异常,如果异常发生,则执行except中的代码 案例:
try:
f = open('python.txt', 'r')
content = f.readline()
print(content)
except:
f = open('python.txt', 'w', encoding='utf-8')
f.write('发生异常,执行except语句中的代码')
f.close()
4 捕获异常并输出错误信息#
无论我们在except后面定义多少个异常类型,实际应用中,也可能会出现无法捕获的未知异常。这个时候,我们考虑使用Exception异常类型捕获可能遇到的所有未知异常:
try:
可能遇到的错误代码
except Exception as e:
print(e)
案例:打印一个未定义变量,使用Exception异常类进行捕获
try:
print(name)
except Exception as e:
print(e)
5 异常捕获中else语句#
else语句:表示的是如果没有异常要执行的代码。
try:
print(1)
except Exception as e:
print(e)
else:
print('哈哈,真开森,没有遇到任何异常')
案例:
try:
f = open('python.txt', 'r')
except Exception as e:
print(e)
else:
content = f.readlines()
print(content)
f.close()
6 异常捕获中的finally语句#
finally表示的是无论是否异常都要执行的代码,例如关闭文件
try:
f = open('python.txt', 'r')
except:
f = open('python.txt', 'w')
else:
content = f.readlines()
print(content)
finally:
f.close()
7 异常案例#
案例需求#
升级猜数字游戏,增加程序健壮性,用户在输入过程中可能不会输入数字或者不按照要求输入,程序要能捕获到用户的异常输入。在已有的猜数游戏中加入异常功能。
实现思路#
①使用python异常捕获try...except,捕获用户异常输入
代码实现#
import random
def guess_number_game():
# 1. 随机生成1个 1 ~ 100之间的数字, 让用户来猜.
guess_num = random.randint(1, 100)
while True:
try:
# 2. 键盘录入, 表示: 玩家出拳的编号.
input_num = int(input('请录入您要猜的整数 (1-100): '))
# 3. 判断用户是否猜对了, 并提示. 猜对, 猜大, 猜小.
if input_num == guess_num:
print('恭喜您, 猜对了, 请找夯老师领取奖品, 练习题一套!')
break
elif input_num > guess_num:
print('哎呀, 您猜大了!')
else:
print('哎呀, 您猜小了!')
except ValueError:
print('输入无效,请输入一个整数!')
# 调用猜数字游戏函数
guess_number_game()
8 debug断点调试#
Debug 是程序开发中非常重要的技能,PyCharm 提供了强大的调试功能。下面详细介绍如何在 PyCharm 中使用断点调试。
基本断点设置#
- 在代码行号右侧点击,会出现红色圆点,表示已设置断点
- 再次点击可取消断点
主要操作按钮:#
- Resume Program (F9) :继续执行直到下一个断点
- Step Over (F8) :执行当前行,不进入函数内部
- Step Into (F7) :进入当前行的函数调用
- Step Out (Shift + F8) :跳出当前函数,回到调用处
- Run to Cursor (Alt + F9) :运行到光标所在位置
小结#
Q1: 什么是异常?
- Python中, 把程序出现的所有非正常情况, 统称为异常.
Q2: 掌握捕获异常的格式.
try: 可能出现问题的代码 Except exception as e: 出现问题后的解决方案 else: 如无异常, 则会执行这里的内容 finally: 无论是否有问题, 都会执行这里的内容.