第8章:文件操作与异常处理(纯小白版)
本章介绍了Python文件操作与异常处理。文件操作包括文本文件的读取('r')、写入('w')和追加('a')三种模式,强调使用with语句自动关闭文件;讲解了CSV和JSON两种数据格式的处理方法。异常处理部分介绍了try-except捕获错误机制和raise主动抛出异常的方法,以及上下文管理器with语句如何安全地管理资源。通过本章学习,可以掌握数据持久化存储和程序健壮性提升的关键技术。
好的,我们来学习第八章。在之前的章节里,我们的程序产生的所有数据,比如变量、列表,都存放在内存里。程序一旦结束,这些数据就消失了。这一章,我们将学习如何将数据永久地保存在文件中,并学习一套“安全带”机制——异常处理,来保证我们的程序在遇到意外情况时不会轻易“崩溃”。
第八章:文件操作与异常处理
8.1 读取与写入文本文件
核心比喻:记事本
-
文件:就像你电脑里的一个
.txt
记事本文件。 -
打开文件
open()
:就像你双击打开这个记事本。打开时你需要决定是想**读('r')里面的内容,还是想写('w')**新的内容。 -
读/写操作:执行实际的读写动作。
-
关闭文件
close()
:就像你点击记事本的关闭按钮,保存你的修改。这是一个非常重要的步骤,忘记关闭可能会导致数据丢失。
第一步:写入一个全新的文件 (Write Mode - 'w')
写入模式 'w'
会创建一个新文件。如果文件已存在,它会清空所有旧内容,然后写入新内容。
-
打开你的Linux终端,我们先用
ls
命令看看当前目录下有什么。 -
进入
python3
交互模式。 -
打开文件。我们准备创建一个名为
Pythonshopping_list.txt
的文件。encoding='utf-8'
是处理中文等非英文字符的标准做法,强烈建议总是加上。>>> f = open('shopping_list.txt', 'w', encoding='utf-8')
-
写入内容。使用
Python.write()
方法。\n
是一个特殊字符,代表“换行”。>>> f.write('鸡蛋\n') >>> f.write('牛奶\n') >>> f.write('面包')
-
关闭文件。这是保存写入内容的关键一步!
Python>>> f.close()
-
验证结果。按
BashCtrl+D
退出Python。在终端里用cat
命令查看文件内容。cat shopping_list.txt
你会看到我们写入的三行内容。
第二步:读取一个已存在的文件 (Read Mode - 'r')
-
再次进入
python3
交互模式。 -
以只读模式打开我们刚才创建的文件。
Python>>> f = open('shopping_list.txt', 'r', encoding='utf-8')
-
读取全部内容。使用
Python.read()
方法。>>> content = f.read()
-
关闭文件。
Python>>> f.close()
-
现在,文件的所有内容都保存在
Pythoncontent
这个字符串变量里了。>>> print(content) 鸡蛋 牛奶 面包
第三步:在文件末尾追加内容 (Append Mode - 'a')
如果你不想清空文件,只想在后面添加新内容,就用'a'
模式。
Python
>>> f = open('shopping_list.txt', 'a', encoding='utf-8')
>>> f.write('\n果汁') # 先换行再追加
>>> f.close()
现在你再用cat shopping_list.txt
查看,会发现“果汁”被加在了最后。
8.2 处理CSV与JSON文件
纯文本文件虽然简单,但如果数据有结构(比如表格),用专门的格式会更方便。CSV和JSON就是两种最常见的数据交换格式。
CSV:像电子表格一样的文本
CSV (Comma-Separated Values) 文件就是用逗号分隔值的文本文件,每一行代表一条记录。Python有内置的csv
模块来轻松处理它。
-
首先,我们用
Bashnano
创建一个students.csv
文件。nano students.csv
输入以下内容(这就是CSV格式):
代码段name,age,grade Alice,20,A Bob,22,B Charlie,21,A
保存并退出。
-
在
Pythonpython3
交互模式中,读取这个文件。>>> import csv >>> with open('students.csv', 'r', encoding='utf-8') as file: ... reader = csv.reader(file) ... for row in reader: ... print(row) ...
讲解:我们使用了
with
语句(稍后会详细讲),它能自动帮我们关闭文件。csv.reader
会把每一行转换成一个字符串列表。你会看到输出:['name', 'age', 'grade'] ['Alice', '20', 'A'] ['Bob', '22', 'B'] ['Charlie', '21', 'A']
JSON:像Python字典和列表一样的文本
JSON (JavaScript Object Notation) 是一种轻量级的数据格式,它的语法和Python的字典、列表几乎一样。它是现代网络API通信的标准。Python用json
模块来处理。
-
在
python3
交互模式中,我们来操作JSON。 -
将Python字典转换为JSON字符串(序列化):
Python>>> import json >>> user_profile = { ... "name": "David", ... "age": 35, ... "is_active": True, ... "courses": ["Python", "Machine Learning"] ... } >>> # json.dumps() 将字典转为JSON字符串, indent=4让格式更美观 >>> user_json = json.dumps(user_profile, indent=4, ensure_ascii=False) >>> print(user_json)
你会看到一段格式优美的、和字典长得一模一样的文本。
-
将JSON字符串转换回Python字典(反序列化):
Python>>> # 假设 user_json 是从文件或网络获取的字符串 >>> restored_dict = json.loads(user_json) >>> print(restored_dict) {'name': 'David', 'age': 35, 'is_active': True, 'courses': ['Python', 'Machine Learning']} >>> print(restored_dict['name']) David
8.3 try...except
:优雅地处理错误
核心比喻:Plan B
在写程序时,很多操作都可能失败。比如你要读取的文件可能不存在,你要转换成数字的字符串可能是"hello",你要除以的数可能是0。如果发生这些异常 (Exception),程序默认会立刻崩溃并报错。
try...except
语句就是给程序一个Plan B。
-
try
代码块:把你认为可能出错的代码放在这里(Plan A)。 -
except
代码块:如果try
里的代码真的出错了,程序不会崩溃,而是会立即跳转到except
代码块里执行(Plan B)。
第一步:体验一次程序崩溃
Python
>>> age_str = "二十"
>>> age_int = int(age_str) # 这行会出错,因为“二十”无法转成数字
程序会抛出ValueError
并终止。
第二步:使用try...except
来避免崩溃
Python
>>> age_str = "二十"
>>> try:
... print("正在尝试转换...")
... age_int = int(age_str) # Plan A: 尝试执行这句危险代码
... print(f"转换成功,年龄是 {age_int}")
... except ValueError: # Plan B: 如果上面的代码触发了 ValueError
... print("转换失败!请输入一个阿拉伯数字。")
...
>>> print("程序继续运行...")
观察输出:你会看到“正在尝试转换...”,然后是“转换失败!...”,最后是“程序继续运行...”。程序没有崩溃,而是执行了我们的Plan B,然后继续向下执行。这就是优雅地处理错误。
你可以捕捉不同类型的异常,比如FileNotFoundError
, ZeroDivisionError
等。
8.4 抛出异常:raise
有时候,Python本身不认为代码有错,但根据你的业务逻辑,它就是错的。比如,函数要求输入一个正数,但用户输入了负数。这时,你可以主动地、人为地触发一个异常,来通知程序的其他部分“这里出问题了!”。这个动作就是抛出 (raise) 异常。
一步一步实践:
-
我们编写一个设置密码的函数,逻辑要求密码长度不能少于8位。
Python>>> def set_password(password): ... if len(password) < 8: ... # 密码长度不够,这是一个业务逻辑错误,我们主动抛出异常 ... raise ValueError("密码长度不能少于8位!") ... print("密码设置成功。") ...
-
使用一个合法的密码调用函数:
Python>>> set_password("MySuperSecret123") 密码设置成功。
-
使用一个不合法的密码调用函数:
Python>>> set_password("12345")
程序立刻被中断,并抛出了我们自己定义的
ValueError
,显示的消息也是我们自己写的。
raise
和 try...except
经常配合使用:你可以在一个地方raise
异常,然后在调用这个地方的更高层级代码里用try...except
来捕捉并处理这个异常。
8.5 上下文管理器与with
语句
核心比喻:自动关门的冰箱
我们回到8.1节的文件操作。我们每次都必须手动执行f.close()
。如果中间代码出了错,f.close()
可能永远不会被执行,文件就会一直被占用,这是一种资源泄露。
with
语句(也叫上下文管理器)就是为了解决这个问题而生的,它能自动管理资源的获取和释放。对于文件来说,它能保证文件在用完后一定会被自动关闭,无论中间是否发生错误。
一步一步体验with
语句的魔力:
-
传统方式(需要手动
Pythonclose
):f = open('my_file.txt', 'w', encoding='utf-8') f.write('hello') f.close()
-
使用
Pythonwith
语句(现代、安全的方式):>>> with open('my_file.txt', 'w', encoding='utf-8') as f: ... f.write('hello, with statement!') ... # 在这个缩进块里,文件是打开的,变量 f 可以使用 ... >>> # 退出缩进块后,Python 会自动帮你执行 f.close()
讲解:
-
with open(...) as f:
:打开文件并将其赋值给变量f
。 -
缩进的代码块就是
with
管理的范围。 -
当代码执行离开这个缩进块时(无论是正常结束还是发生错误),Python都会自动、必定地关闭文件。
-
给小白的最终建议: 永远、永远、永远使用 with open(...)
的方式来处理文件! 这是最安全、最简洁、最现代的Pythonic方式,它能让你免于忘记关闭文件的烦恼。
更多推荐
所有评论(0)