前言
在实际的开发过程中会经常要将数据作持久化处理,通常的做法是将数据从内存写到磁盘文件中
本文将带你学习Python对于文件的读写操作,以及在如何保证代码的健壮性和容错性;异常的捕获必不可少,这里仅列举一些常见的异常
python中使用open内置函数来打开文件,可以指定文件名(相对路径和绝对路径)、操作模式(读/写/追加)、编码格式(一般为utf-8).
读写文本文件
读写文件一般使用open方法,也可以使用 with open();
with关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源
- 一次性读取整个文件的内容,适合文件数量比较小的情况。
def main():
fr = None
try:
# 使用open打开文件
fr = open("../python_base/python_turtle.py", 'r', encoding='utf-8')
# 一次性读取整个文件
print(fr.read())
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定编码错误")
except UnicodeDecodeError:
print("读取文件时解码错误")
finally:
if fr:
# 读完文件后要手动关闭文件
fr.close()
if __name__ == '__main__':
main()
- 通过for … in循环逐行读取
def main():
try:
# for-in循环逐行读取
with open("../python_base/python_turtle.py", 'r', encoding='utf-8') as f:
for line in f:
print(line, end='')
print()
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定编码错误")
except UnicodeDecodeError:
print("读取文件时解码错误")
if __name__ == '__main__':
main()
- readline和readlines读取
readline只读取一行内容,readlines读取所有内容到一个列表中
def main():
try:
# 通过with关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源
with open("../python_base/python_turtle.py", 'r', encoding='utf-8') as f:
print(f.readline()) # 读取一行文件
print(f.readlines()) # readlines()按行读取文件到列表中
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定编码错误")
except UnicodeDecodeError:
print("读取文件时解码错误")
if __name__ == '__main__':
main()
- 写入文件
写入文件使用编码 ‘w’ 操作模式
def main():
try:
# 写入文件
with open('../test.py', mode='w', encoding='utf-8') as fw:
fw.write(fr.read())
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定编码错误")
except UnicodeDecodeError:
print("读取文件时解码错误")
if __name__ == '__main__':
main()
- 读写二进制文件
‘rb’,‘wb’ 是读写二进制模式
def main():
try:
# 读写二进制文件
with open("../assets/004.jpg", 'rb') as frb:
data = frb.read()
print(data)
with open("../assets/004.jpg", 'wb') as frb:
print(frb.write(data))
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定编码错误")
except UnicodeDecodeError:
print("读取文件时解码错误")
if __name__ == '__main__':
main()
序列化和反序列化
序列化(serialization):当需要将变量和对象持久化存储到磁盘中或在网络上进行传输时,我们需要将变量或者对象转化为二进制流的形式,从而将其转换为二进制流的过程。
反序列化:是将序列化的对象从磁盘中转移到内存中,同时将二进制流转换为原来的数据格式。
- pickle模块
import pickle
# dump和dumps是序列化,load和loads是反序列化
dict1 = {'a': 1, 'b': 2}
dict2 = pickle.dumps(dict1)
print(dict2, type(dict1), type(dict2), id(dict1), id(dict2))
dict3 = pickle.loads(dict2)
print(dict3, type(dict3), id(dict1), id(dict2), id(dict3))
# dump 和 load 是序列化和反序列化到文件中
file1 = open('../assets/004.jpg', 'wb')
file2 = pickle.dump(dict1, file1)
print(file2, type(file2))
file1.close()
file3 = open('../assets/004.jpg', 'rb')
file4 = pickle.load(file3)
print(file4, type(file4))
file3.close()
- Json模块
json.dumps():将python数据格式转换为json的字符串格式
json.loads():将json的字符串格式转换为python的数据格式
json.dump:序列化到文件中
json.load: 将文件中的内容反序列化
import json
dict1 = {'a': 1, 'b': 2}
dict2 = json.dumps(dict1)
print(dict2, type(dict2), id(dict2))
dict3 = json.loads(dict2)
print(dict3, type(dict3), id(dict3))
# json.dump:序列化到文件中 json.load: 将文件中的内容反序列化
dict1 = {'a': 1, 'b': 2}
file1 = open('../assets/004.jpg', 'w')
file2 = json.dump(dict1, file1)
print(file2, type(file2))
file1.close()
file3 = open('../assets/004.jpg', 'r')
file4 = json.load(file3)
print(file4, type(file4))
file3.close()
常见的异常
- 常见的异常
NameError:尝试访问一个未申明的变量
ZeroDivisionError:除数为零
SyntaxErrot:解释器语法错误
IndexError:请求的索引元素超出序列范围
KeyError:请求一个不存在字段关键字
ValueError:请求一个不存在字段值错误
IOError:输入/输出错误
AttributeError:尝试访问未知的对象错误
ImportError:导入模块错误
IndentationError:语法缩进错误
KeyboardInterrupt:ctrl+C
SyntaxError:代码语法错误
TypeError:传入对象类型与要求不符合
MemoryError 内存溢出错误(对于python解释器不是致命的)
RuntimeError:一般的运行时错误
- python中通过raise来主动抛出异常
def main(a):
if not isinstance(a, str):
raise TypeError('this obj must be string')
return a
- 跟踪异常栈
import traceback
print(traceback.format_exc())