10.文件和异常
10.1从文件中读取数据
10.1.1读取整个文件
1、直接使用文件名
当需要读取的文件和代码文件在同一个目录下时,读取文件使用函数open()打开文件,括号使用单引号引出文件名,同时使用read()来读取这个文件的全部内容。示例如下:
with open('test.txt') as file_object:
#使用with可以打开文件并关闭
contents = file_object.read()
#将文件赋给变量contents并读取
print(contents)
此时输出结果为:
3.1415926535
8979323846
2643383279
虽然输出,但可以看到相比于源文件输出结果末尾多了一个空行。这是因为read()到达文件末尾时返回了一个空字符串,要删除这个多出来的空行,可在函数调用print()使用rstrip()。示例如下:
with open('test.txt') as file_object:
contents = file_object.read()
print(contents.rstrip())
此时输出结果为:
3.1415926535
8979323846
2643383279
可以看到,已经没有末尾的空行啦。
2、使用相对路径
如果需要读取的文件在代码目录的子目录中,就需要指定相对路径,示例如下:
with open('xinjianwenjianjia/test.txt') as file_object:
contents = file_object.read()
print(contents)
此时输出结果一致。需要注意的是,在显示文件路径时,使用反斜杠(\)而不是斜杠(/)。
3、使用绝对路径
在以上两种方式行不通时,可以使用绝对路径,即提供所需要读取的文件的完整路径。示例如下:
with open('D:/AAAAAuseful/计算机二级/test.txt') as file_object:
contents = file_object.read()
print(contents)
此时输出结果一致。在这种方式中,可以读取系统中任何地方的文件。
10.1.2逐行读取文件
当我们需要在文件中查找特定的信息时,可以逐行读取文件,可使用for循环对文件进行遍历。示例如下:
filename = 'D:/AAAAAuseful/计算机二级/test.txt'
with open(filename) as file_object:
for line in file_object:
print(line)
此时输出结果变为:
3.1415926535
8979323846
2643383279
但是可以看到,这样输出时,每一行之间都有空格,为了消除每行之间的空格,依然可以使用rstrip()。示例如下:
filename = 'D:/AAAAAuseful/计算机二级/test.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
此时输出结果已经变为:
3.1415926535
8979323846
2643383279
10.1.3创建一个包含文件各行内容的列表
使用关键字with时,open()打开的文件对象只能够在with代码块内可用,如果要在with代码块之外访问文件的内容,可以在with代码块内将文件的各行内容存储在一个列表之中,并且在with代码块之外使用该列表,这样就可以立即处理文件的各个部分,也可以推迟到程序后面再处理。示例如下:
filename = 'D:/AAAAAuseful/计算机二级/test.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
这样依然可以输出文件内容。
10.1.4使用文件的内容
示例如下:
filename = 'D:/AAAAAuseful/wzu/计算机二级/test.txt'
with open(filename) as file_object:
lines = file_object.readlines()
#创建一个空变量用来存储
pi_string = ''
for line in lines:
#在各行加入字符
pi_string += line.rstrip()
print(pi_string)
输出结果为:
3.1415926535 8979323846 2643383279
我们也可以用strip()来删除这之间的空格。示例如下:
filename = 'D:/AAAAAuseful/wzu/计算机二级/test.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string)
输出结果为:
3.141592653589793238462643383279
10.2写入文件
- 打开文件的模式的参数
参数 | 含义 |
---|---|
r | 只读方式打开文件,文件的指针放在文件的开头 |
rb | 以只读且二进制格式打开文件,文件指针将会放在文件的开头 |
r+ | 打开一个文件用于读写,指针放在文件的开头 |
rb+ | 以二进制格式打开一个文件用于读写,指针放在文件的开头 |
w | 打开文件只用于写入。如果该文件已存在则将其覆盖;如果该文件不存在,创建新文件 |
wb | 以二进制格式打开文件,只用于写入。如果该文件已存在则将其覆盖;如果该文件不存在,创建新文件 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖;如果该文件不存在,创建新文件 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖;如果该文件不存在,创建新文件 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写 |
写入文件时,可以使用以下两种方法:
1、直接使用open()
示例如下:
filename = open('/Users/alice/test.txt', 'w')
filename.write('ocr')
filename.close()
在这里直接使用open()打开了文件,其中向open提供了两个参数,第一个是要写入的文件的具体位置和名字,第二个是打开文件的参数,具体各种见上表格。再使用 write() 函数将一个字符串写入文件。
需要注意的是,python只能将字符串写入文本文件,要将数值数据存储到文本文件中时必须先使用函数str()将其转换为字符串格式。
另外,函数write()不会在写入文本末尾添加换行符,因此如果需要将文本内容放在不同的行,需要在文本中添加指定换行符。
2、使用with open()
示例如下:
with open('/Users/alice/output.txt','w') as filename:
filename.write('result')
10.3存储数据
10.3.1使用模块json
模块json能够将简单的数据结构转储在文件之中,并在程序再次运行时加载该文件中的数据。现在我们来编写一个存储一组数的简短程序,再编写一个将这些数读取到内存中的程序。
1、json.dump()
函数json.dump()接受两个实参:要存储的数据和可用于存储数据的文件对象。 示例如下:
import json
numbers = [2,3,5,7,9,11]
filename = 'numbers.json'
with open(filename,'w') as f:
json.dump(numbers,f)
2、json.load()
函数json.load()用以将存储的文件读取到内存中。只需要接受一个参数即文件名,但需要确保读取的是之前写入的文件。示例如下:
import json
filename = 'numbers.json
with open(filename) as f:
numbers = json.load(f)
print(numbers)
输出结果为:
[2, 3, 5, 7, 9, 11]
###10.3.2保存和读取用户生成的数据
示例如下:
import json
username = input('What is your name?')
#提示用户输入姓名并将其赋给一个变量
filename = 'username.json'
with open(filename,'w') as f:
#调用json。dump(),将用户名和文件对象传递给它,从而将用户名存储到文件中
json.dump(username,f)
#打印信息,指出存储了用户输入的信息
print(f"We'll remember you when you come back,{username.title()}!")
输入数据并打印,可以看到输出结果为:
What is your name?faxxtty
We'll remember you when you come back,Faxxtty!
现在再编写一个程序,向已经存储了名字的用户发出问候:
import json
filename = 'username.json'
with open (filename) as f:
username = json.load(f)
print(f'Welcome back,{username.title()}!')
输出结果为:
Welcome back,Faxxtty!
对于这样两个代码块,可以使用try-except代码块 将两者合并到一个程序之中。示例如下:
import json
filename = 'username.json'
"""如果以前存储了用户名,就加载它。
否则就提示用户输入用户名并存储它"""
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input('What is your name?')
with open(filename,'w') as f:
json.dump(username,f)
print(f"We'll remember you when you come back,{username.title()}!")
else:
print(f'Welcome back,{username.title()}!')