Python ❀ 文件与异常
Posted 无糖可乐没有灵魂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python ❀ 文件与异常相关的知识,希望对你有一定的参考价值。
文章目录
1、文件中读取数据
文本文件可以存储的数据较多,因此Python需要使用文本文件中的信息;
1.1 读取文件
创建一个文件,包含一些数据,使用Python读取文件内容;
with open('test.txt') as fp:
contents = fp.read()
print(contents)
输出结果:
this is test1!
this is test2!
this is test3!
this is test4!
1.2 文件路径
大多数情况下,Python需要打开的文件路径并不是当前Python文件创建的文件路径下,因此就需要告诉Python去那个地方寻找目标文件;Linux系统使用斜杠 / 区分目录层级,而Windows系统使用反斜杠 \\ 区分目录层级,反斜杠在Python中以为转义字符,因此在Windows系统中就需要对目录层级进行转义方可正确识别;若目标文件在当前Python文件目录或当前目录下,推荐使用相对路径,若在其他位置,推荐使用绝对路径寻找目标文件;
- 在Windows系统下使用绝对路径找寻文件;
file_path = "D:\\\\Python\\\\Test\\\\Source\\\\StudyCode\\\\test.txt"
with open(file_path) as fp:
contents = fp.read()
print(contents)
- 在Linux系统下使用绝对路径找寻文件;
[root@VM-8-10-centos ~]# python3 a.py
this is linux1
[root@VM-8-10-centos ~]# cat a.txt
this is linux1
[root@VM-8-10-centos ~]# cat a.py
file_path = '/root/a.txt'
with open(file_path) as fp:
contents = fp.read()
print(contents)
[root@VM-8-10-centos ~]# python3 a.py
this is linux1
read()到达文件末尾返回一个空白字符串,将这个空白字符串显示为一个空行,可以使用rstrip()删除末尾的空白
[root@VM-8-10-centos ~]# cat a.py
file_path = '/root/a.txt'
with open(file_path) as fp:
contents = fp.read()
print(contents.rstrip())
[root@VM-8-10-centos ~]# python3 a.py
this is linux1
1.3 逐行读取
读取文件时,需要检查文件内的每一行;若需要从文件内查找某个特定行,就需要逐行读取文件内容,并返回到指定位置;
with open("test.txt") as fp:
for line in fp:
print(line)
输出结果:
this is test1!
this is test2!
this is test3!
this is test4!
将文件读取的内容存储在变量中,此时打印每一行都会出现空行,由于每行数据都存在一个换行符,print函数也会加上此换行符,因此每行末尾都会有两个换行符,一个是print语句自身的换行,一个是文件内每行的换行,需要消除这些空行,就需要使用rstrip();
with open("test.txt") as fp:
for line in fp:
print(line.rstrip())
输出结果:
this is test1!
this is test2!
this is test3!
this is test4!
1.4 创建一个包含文件各行内容的列表
使用with时,open()返回的文件对象只能在with代码内可用,如果需要其他处使用,则需要将文件内容存储至一个列表中,并在with代码外使用此列表,就可以处理文件的各个部分;
with open("test.txt") as fp:
lines = fp.readlines()
print(lines)
输出结果:
['this is test1!\\n', 'this is test2!\\n', 'this is test3!\\n', 'this is test4!']
1.5 使用文件内容
将文件读取至内存时,就可以修改这些数据;
with open("test.txt") as fp:
lines = fp.readlines()
st1 = ''
for line in lines:
# 修改注意消除空行与空白字符
st1 += line.strip()
print(st1)
print(len(st1))
输出结果:
this is test!this is test!this is test!this is test!
52
2、写入文件
保存数据最简单的方法就是将其写入到文件中,通过输出写入文件,即便关闭了程序窗口,这些数据仍然存在,不会被修改或删除;
2.1 写入空白文件
若需要将文本写入文件,需要使用open()函数的一个实参w,告知Python需要写入打开的文件;open()函数中第一个实参为打开的文件路径,可以为变量值;第二个实参为文件模式,支持 读取模式(r)、写入模式(w)、附加模式(a)、读取和写入模式(r+),默认选择模式为读取模式,在写入模式或附加模式下,若目标文件不存在,在Python会自动创建一个空白文件用于存储数据;
fp = 'test.txt'
with open(fp,'w') as file:
file.write('this is test!')
输出结果:
# 查看目标文件内容
this is test!
2.2 写入多行
函数write()不会再写入的文件末尾添加换行符,因此若是需要写入多行数据,需要在代码中添加换行符,以进行换行写入操作;
- 不添加换行符
fp = 'test.txt'
with open(fp,'w') as file:
file.write('this is test1!')
file.write('this is test2!')
输出结果:
this is test1!this is test2!
- 添加换行符
fp = 'test.txt'
with open(fp,'w') as file:
file.write('this is test1!\\n')
file.write('this is test2!')
输出结果:
this is test1!
this is test2!
除了换行符,还支持其他操作符,如制表符、空格等常见操作符;
2.3 附加到文件
若需要给文件添加内容,而不是覆盖原有内容,则需要使用附加模式(a)打开文件;以附加模式打开文件,Python不会清空之前的数据,而是将新数据添加至文件末尾;
fp = 'test.txt'
with open(fp,'a') as file:
file.write('this is test3!\\n')
file.write('this is test4!')
输出结果:
this is test1!
this is test2!
this is test3!
this is test4!
3、异常处理
Python使用被称为异常的特殊对象来管理程序并执行期间发生的错误,每当发生让Python不知错误时,就会产生一个异常对象;若是编写了异常处理代码,则会继续运行;若未编写异常处理代码,则会返回一个traceback,包含了异常的报告;
3.1 处理ZeroDivisionError异常
下面引入一个异常,以0做除数;
print(1/0)
输出结果:
Traceback (most recent call last):
File "D:\\Python\\Test\\Source\\StudyCode\\05_study_test.py", line 1, in <module>
print(1/0)
ZeroDivisionError: division by zero
首先ZeroDivisionError指出了异常对象是什么类型,其次division by zero说明了异常出现的原因;
3.2 使用try-except处理异常
当你认为可能会发生错误时,可以编写一个处理异常代码来处理可能引发的异常;
try:
print(1/0)
except ZeroDivisionError:
print("divide is not zero!")
输出结果:
divide is not zero!
try接收可能会出现异常的代码内容,except需要指定错误类型,如果错误类型匹配,则执行下面的代码内容;
try:
[可能出现异常的代码]
except [异常类型]:
[异常类型匹配成后执行的代码]
3.3 使用异常避免崩溃
当程序未执行完成出现异常时,会直接中断当前代码执行过程,返回异常对象;如果能够正确处理异常,就可以避免代码出现崩溃现象;
print('Give me to numbers\\nand i will divide them ')
fir_number = input('First number is :')
last_number = input('Last number is :')
answer = int(fir_number) / int(last_number)
print(answer)
输出结果:
Give me to numbers
and i will divide them
First number is :5
Last number is :0
Traceback (most recent call last):
File "D:\\Python\\Test\\Source\\StudyCode\\05_study_test.py", line 6, in <module>
answer = int(fir_number) / int(last_number)
ZeroDivisionError: division by zero
程序崩溃时,无法继续执行后续代码,会导致用户使用效果极差;因此在可能出现异常的地方,需要使用异常处理代码来避免异常导致的代码崩溃出现;
print('Give me to numbers\\nand i will divide them ')
fir_number = input('First number is :')
last_number = input('Last number is :')
try:
answer = int(fir_number) / int(last_number)
print(answer)
except ZeroDivisionError:
print('division not by zero')
输出结果:
Give me to numbers
and i will divide them
First number is :5
Last number is :0
division not by zero
3.4 else代码块
在try-except代码中还有一个else代码块,else执行为try后结果;
print('Give me to numbers\\nand i will divide them ')
fir_number = input('First number is :')
last_number = input('Last number is :')
try:
answer = int(fir_number) / int(last_number)
except ZeroDivisionError:
# 当try代码执行过程匹配到ZeroDivisionError异常时,运行except代码内容
print('division not by zero')
else:
# 当try代码执行正常无异常时,运行else代码内容
print(answer)
输出结果:
Give me to numbers
and i will divide them
First number is :5
Last number is :1
5.0
3.5 处理FileNotFoundError异常
使用文件时,最常见的问题就是文件路径错误导致文件打开失败,
# 文件路径选择一个不存在的文件
filename = 'file.txt'
with open(filename,'r') as fp:
content = fp.read()
print(content)
输出结果:
Traceback (most recent call last):
File "D:\\Python\\Test\\Source\\StudyCode\\05_study_test.py", line 3, in <module>
with open(filename,'r') as fp:
FileNotFoundError: [Errno 2] No such file or directory: 'file.txt'
由于文件不存在,因此报出FileNotFoundError异常,此异常的触发是由于open()函数未找到对应的file.txt文件,因此将此处代码使用try-except进行异常处理就可以避免代码崩溃;
filename = 'file.txt'
try:
with open(filename) as fp:
content = fp.read()
except FileNotFoundError:
print( filename + ' is not found! ')
else:
print(content)
输出结果:
file.txt is not found!
3.6 分析文本
当经过异常处理后的代码可以使用else代码块继续执行异常判断结果,因此就可以对其结果进行其他操作;
split()以空格为分隔符号将字符串拆分成多个部分,并将其存储至一个列表中;
filename = 'test.txt'
try:
with open(filename) as fp:
content = fp.read()
except FileNotFoundError:
print( filename + ' is not found! ')
else:
num_words = len(content.split())
print('the file ' + filename + ' has about ' + str(num_words) + ' words ')
输出结果:
the file test.txt has about 12 words
3.7 使用多个文件
下面将统计单词的代码变更为函数,并使用遍历方法,输入多个文件,执行函数内异常判断与统计单词;
# 函数
def count_words(filename):
try:
with open(filename) as fp:
content = fp.read()
except FileNotFoundError:
print(filename + ' is not found! ')
else:
num_words = len(content.split())
print('the file ' + filename + ' has about ' + str(num_words) + ' words ')\\
if __name__ == '__main__':
filenames = ['test.txt','a.txt','b.txt']
# 遍历多个文件名称
for filename in filenames:
count_words(filename)
输出结果:
the file test.txt has about 12 words
a.txt is not found!
b.txt is not found!
3.8 异常触发无回显
一般情况下,当代码出现异常时不能出现返回信息,继续让代码执行,直到执行结束;
def count_words(filename):
try:
with open(filename) as fp:
content = fp.read()
except FileNotFoundError:
# 匹配异常时,什么都不执行
pass
else:
num_words = len(content.split())
print('the file ' + filename + ' has about ' + str(num_words) + ' words ')\\
if __name__ == '__main__':
filenames = ['a.txt','b.txt','test.txt']
for filename in filenames:
count_words(filename)
输出结果:
the file test.txt has about 12 words
4、存储数据
很多程序要求用户输入某种信息,如让用户存储某些数据,程序需要把用户提供的数据存储在列表和字典等数据结构中,用户关闭程序时,数据需要被保存某个地方;最简单的方法就是使用json模块来存储数据;
JSON(javascript Object Notation)格式最初是为JavaScript开发的,随后成为了一周常见格式,被包含在Python的一个模块中;
4.1 使用json.dump()与json.load()
编写一个存储数字的简单程序,使用json.dump存储这组数字;
import json
numbers = [1,2,3,4,5,46,6,23,4,5,2,3]
filename = 'json.json'
with open(filename,'w') as fp:
# 若目标文件不存在,写入模式会自动创建空白文件
json.dump(numbers,fp)
输出结果:
# 打开json.json文件查看
[1, 2, 3, 4, 5, 46, 6, 23, 4, 5, 2, 3]
使用json.load()读取这组数字;
import json
filename = 'json.json'
with open(filename) as fp:
numbers = json.load(fp)
print(numbers)
输出结果:
[1, 2, 3, 4, 5, 46, 6, 23, 4, 5, 2, 3]
4.2 保存和读取用户生成的数据
对于用户生成的数据,使用json保存将大有益处,如果不以某种方式存储数据,当程序执行结束或停止会丢失数据;
编写一个程序,输入用户名,将其保存至某个文件内;
import json
username = input("please input your name:")
filename = "username.json"
with open(filename,"w") as fp:
json.dump(username,fp)
print("we will remember you when you come back, " + username + " !")
输出结果:
"zxc"
编写一个程序,向被存储到文件的用户名发送一个信息;
import json
filename = 'username.json'
with open(filename,"r") as fp:
username = json.load(fp)
print("welcome back, " + username + " !")
输出结果:
welcome back, zxc !
将这两个程序结合起来,尝试从文件username.json获取用户名,若文件不存在,使用异常处理输入用户名,将其存储在username.json文件内,若文件存在则向文件内的用户名发送一个信息;
import json
filename = 'username.json'
try:
with open(filename,"r") as fp:
username = json.load(fp)
except FileNotFoundError:
username = input("please input your name:")
filename = "username.json"
with open(filename, "w") as fp:
json.dump(username, fp)
print("we will remember you when you come back, " + username + " !")
else:
print("welcome back, " + username + " !")
首先打开username.json文件,若文件存在,则读取文件内用户名,并执行else代码块,返回一个信息;若文件不存在,将引发FileNotFoundError异常,执行except代码块,需要输入一个用户名,创建文件并将其保存在文件内;
4.3 重构
代码能够正确运行,但是可以做进一步的改进,将代码划分为一些列完成具体工作的函数,这种过程称为重构;重构之后的代码更清晰、易于理解、容易扩展;
此处将上面的代码进行重构;
import json
def greet_user():
filename = 'username.json'
try:
with open(filename, "r") as fp:
username = json.load(fp)
except FileNotFoundError:
username = input("please input your name:")
filename = "username.json"
with open(filename, "w") as fp:
json.dump(username, fp)
print("we will remember you when you come back, " + username + " !")
else:
print("welcome back, " + username + " !")
if __name__ == '__main__':
greet_user()
输出结果:
welcome back, zxc !
虽然使用了一个函数,但是这个函数中包含了太多了功能,需要将其功能分为不同函数进行执行,继续重构代码;
import json
# 函数-获取存储的用户名
def get_username():
filename = 'username.json'
try:
with open(filename, "r") as fp:
username = json.load(fp)
except FileNotFoundError:
# 不存在返回空
return None
else:
# 存在返回文件内容
return username
# 函数-校验文件内用户名是否存在
def greet_user():
username = get_username()
# 使用获取的用户名进行判断
if username:
# 用户名存在则发现信息
print("welcome back, " + username + " !")
else:
# 用户名不存在,则创建用户名并保存到文件
username = input("please input your name:")
filename = "username.json"
with open(filename, "w") as fp:
json.dump(username, fp)
print("we will remember you when you come back, " + username + " !")
if __name__ == '__main__':
greet_user()
此处get_user函数中仍然存在多个功能,因此将功能提取到一个单独的函数中;
import json
def get_username(Python入门--18--异常与try,except语句