第10章 文件和异常
- 10.1 从文件中读取数据
- 10.1.1 读取整个文件
- 10.1.2 文件路径
- 10.1.3 逐行读取
- 10.1.4 创建一个包含文件各行内容的列表
- 10.1.5 使用文件的内容
- 10.1.6 包含一百万位的大型文件
- 10.1.7 圆周率值中包含你的生日吗
- 10.2 写入文件
- 10.2.1 写入文件
- 10.2.2 写入多行
- 10.2.3 附加到文件
- 10.3 异常
- 10.3.1 处理 ZeroDivisionError 异常
- 10.3.2 使用 try-except 代码块
- 10.3.3 使用异常避免崩溃
- 10.3.4 else 代码块
- 10.3.5 处理 FileNotFoundError 异常
- 10.3.6 分析文本
- 10.3.7 使用多个文件
- 10.3.8 静默失败
- 10.3.8 决定报告哪些错误
- 10.4 存储数据
- 10.4.1 使用 json.dump()和 json.load()
- 10.4.2 保存和读取用户生成的数据
- 10.4.3 重构
10.1 从文件中读取数据
10.1.1 读取整个文件
要读取文件,需要一个包含几行文本的文件。
path ='E:/test.txt'
with open(path) as file:data = file.read()
print(data)
open 接受一个文件路径,返回一个表示文件的对象,并将该对象赋给file使用。方法read()会读取文件的全部内容。
输出时字符后面后多一个空行,可通过rstrip()删除字符后面的空白。
print(data.rstrip)
10.1.2 文件路径
将类似于 test.txt 的文件名传递给函数时,Python 将在当前执行的文件中查找。
绝对文件路径 ‘E:/test.txt’ 在计算机中的准确位置。
相对文件路径 ‘test.txt’ 在当前执行的文件(.py文件)所在的目录中查找。
10.1.3 逐行读取
要以每次一行的方式检查文件,可对文件对象使用 for 循环。
path ='E:/test.txt'
with open(path) as file:for line in file:print(line)
10.1.4 创建一个包含文件各行内容的列表
使用关键字 with 时,open()返回的文件对象只在 with 代码块内可用。如果要访问文件的内容,可在 with 代码块内将文件的各行存储在一个列表中。
path ='E:/test.txt'
with open(path) as file:lines = file.readlines()
for line in lines:print(line.rstrip())
10.1.5 使用文件的内容
将文件读取到内存中后,就能以任何方式使用这些数据了。
path ='E:/test.txt'
with open(path) as file:lines = file.readlines()
ss = ''
for line in lines:ss += line.rstrip() # 将字符串连接起来 且没有空格
print(ss)
10.1.6 包含一百万位的大型文件
创建一个包含所有这些数字的字符串,将这个文件传递给它
10.1.7 圆周率值中包含你的生日吗
将生日表示为一个由数字组成的字符串,再检查这个字符串是否包含在中。
path ='E:/test.txt'
with open(path) as file:lines = file.readlines()
ss = ''
for line in lines:ss += line.rstrip()
print(ss) # abcdefg
s = 'a'
if s in ss:print('包含')
else:print('不包含')
10.2 写入文件
10.2.1 写入文件
path ='E:/test.txt'
with open(path, 'w') as file:file.write('python')
调用open()时提供了两个实参,第一个实参是要打开的文件的名称。第二个实参’w’是写入模式。
第二个参数 ‘r’读取模式,‘w’写入模式,‘a’附加模式,‘r+’读写模式。默认只读‘r’。
如果写入的文件不存在,函数open()将自动创建它。如果以写入模式(‘w’)打开,指定的文件已经存在,python将在返回文件对象前清空该文件的内容。
10.2.2 写入多行
函数 write()不会在写入的文本末尾添加换行符,因此写入多行时需要指定换行符’\n’。
path ='E:/test.txt'
with open(path, 'w') as file:file.write('hello\n')file.write('python\n')
10.2.3 附加到文件
如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式’a’打开文件。
path ='E:/test.txt'
with open(path, 'a') as file:file.write('hello\n')file.write('python\n')
10.3 异常
10.3.1 处理 ZeroDivisionError 异常
不能用数除以 0。
print(5/0)
10.3.2 使用 try-except 代码块
当你认为可能会发生错误时,可编写一个 try-except 代码块来处理可能引发的异常。
try:print(5/0)
except ZeroDivisionError:print('不能除以0')
10.3.3 使用异常避免崩溃
发生错误时,如果程序还有工作尚未完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。
10.3.4 else 代码块
有一些仅在 try 代码块成功执行时才需要运行的代码,这些代码应放在 else 代码块中。
try:ans = 5/4
except ZeroDivisionError:print('不能除以0')
else:print(ans)
10.3.5 处理 FileNotFoundError 异常
找不到文件。查找的文件可能在其他地方,可使用 try-except 代码块以直观的方式处理。
try:path = 'F:/test.txt'with open(path) as file:data = file.read()
except FileNotFoundError:print('找不到文件')
10.3.6 分析文本
split()以空格为分隔符将字符串分拆成多个部分,并将这些部分存储到一个列表中。
我们将对整篇小说调用 split(),再计算得到的列表包含多少个元素,从而确定整篇文本中包含多少个单词。
try:path = 'E:/test.txt'with open(path) as file:data = file.read()
except FileNotFoundError:print('找不到文件')
else:words = data.split()print(len(words)) # 输出单词个数
10.3.7 使用多个文件
编写一个简单的循环,计算要分析的任何文本包含多少个单词。
10.3.8 静默失败
Python有一个 pass 语句,可用于让 Python 在代码块中什么都不要做。
10.3.8 决定报告哪些错误
凭借经验可判断该在程序的什么地方包含异常处理块,以及出现错误时该向用户提供多少相
关的信息。
10.4 存储数据
10.4.1 使用 json.dump()和 json.load()
这是一种在程序之间共享数据的简单方式。
json.dump()接受两个实参:要存储的数据,以及可用于存储数据的文件对象。
json.load()加载数据。
import jsonnums = [1, 2, 3, 4, 5]
path = 'E:/test.json'
with open(path, 'w') as f:json.dump(nums, f) # 写入with open(path) as f:data = json.load(f) # 读取
print(data) # [1, 2, 3, 4, 5]
10.4.2 保存和读取用户生成的数据
使用 json 保存用户生成的数据
10.4.3 重构
重构让代码更清晰、更易于理解、更容易扩展。