文件和异常
实际开发中需要对数据进行持久化操作,而数据的持久化最简单直接的方式就是将数据保存到文件中。python中实现文件的读写操作非常简单,通过内置的open函数,可以指定文件名、操作模式、编码信息等。
操作方式 | 具体含义 |
---|---|
‘r’ | 读取 |
‘w’ | 写入覆盖 |
‘x’ | 写入,文件已经存在则产生异常 |
‘a’ | 追加,不覆盖 |
‘b’ | 二进制模式 |
‘t’ | 文本模式 |
‘+’ | 更新可读可写 |
## 读写文本文件 | |
读取文本文件时,需要在使用open函数时指定好带路径的文件名(可以使用相对路径或绝对路径)并将文件模式设置为’r’(如果不指定,默认值也是’r’),然后通过encoding参数指定编码(如果不指定,默认值是None,那么在读取文件时使用的是操作系统默认的编码) |
def main():
f = open("思考", 'r', encoding="utf-8")
print(f.read)
f.close()
if __name__ == "__main__":
main
如果文件不存在将会产生异常,所以要有try-except操作,或者或许的with操作
def main():
f = None
try:
f = open("思考", 'r', encoding='utf-8')
print(f.read())
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定了未知的编码")
except UnicodeDecodeError:
print("读取文件时解码错误")
finaaly:
if f:
f.close()
if __name__ == "__main__":
main()
with上下文环境
def main():
try:
with open("思考",'r',encoding='utf-8') as f:
print(f.read())
except FileNotFoundError:
print("无法打开指定的文件")
except LookupError:
print("指定了未知的编码")
except UnicodeDecodeError:
print("读取文件时解码错误")
if __name__ == "__main__":
main()
还可以for-in循环逐行的读取或者用readlines方法将文件按行读取
import time
def main():
# 一次性读取整个文件内容
with open("thinking", 'r', encoding='utf-8') as f:
print(f.read())
# 通过for-in循环逐行读取
with open("thinking", 'r', encoding='utf-8') as f:
for line in f:
print(line, end='')
time.sleep(0.5)
print()
# 读取文件按行读取到列表中
with open("thinking", 'r', encoding='utf-8') as f:
lines = f.readlines()
print(lines)
if __name__ == "__main__":
main()
写入文件
from math import sqrt
def is_prime(n):
'''判断是不是素数'''
assert n > 0
for factor in range(2, int(sqrt(n)) + 1):
if n % factor == 0:
retrun False
return True if n != 1 else False
def main():
filenames = ('a.txt', 'b.txt'. 'c.txt')
fs_list = []
try:
for filename in filenames:
fs_list.append(open(filename, 'w', encoding='utf-8'))
for number in range(1, 10000):
if is_prime(number):
if number < 100:
fs_list[0].write(str(number) + '\n')
elif number < 1000:
fs_list[1].write(str(number) + '\n')
else:
fs_list[2].write(str(number) + '\n')
except IOError as ex:
print(ex)
print("写文件发生错误")
finally:
for fs in fs_list:
fs.close()
print("操作完成")
if __name__ "__main__":
main()
读写二进制文件 复制图片
def main():
try:
with open("guido.jpg", "rb") as fs1:
data = fs1.read()
print(type(data)) # bytes
with open("吉多.jpg", "wb") as fs2:
fs2.write(data)
except FileNotFoundError as e:
print("指定的文件无法打开")
except IOError as e:
print("读写文件时出现错误")
print("程序执行结束")
if __name__ == "__main__":
main()
读写JSON文件
如果希望把一个列表或者一个字典中的数据保存到文件中,就以json格式进行保存
json “JavaScript Object Notation”,它本来是JavaScript语言中创建对
象的一种字面量语法,现在已经被广泛的应用于跨平台跨语言的数据交换,因为json也是纯文本,任何系统任何语言处理纯文本都是没有问题的,目前json基本上已经取代了XML作为异构系统间交换数据的事实标准。
JSON示例
{
"name": "bayhax",
"age": "24",
"qq": 14023233,
"friends": ["尹天仇", "阿星"],
"cars": [
{"brands": "BYD", "max_speed": 180},
{"brands": "Audi", "max_speed": 280},
{"brands": "Benz", "max_speed": 320}
]
}
JSON格式跟Python中的字典是一样的
JSON | Python |
---|---|
object | dict |
array | list |
string | str |
number(int/real) | int/float |
true/false | True/False |
null | None |
Python | JSON |
---|---|
dict | object |
list,tuple | array |
str | string |
int float int- & float-derived Enums | number |
True/False | true/false |
None | null |
使用Python中的json模块就可以将字典或列表以JSON格式保存到文件中
import json
def main():
mydict = {
"name": "bayhax",
"age": "24",
"qq": 14023233,
"friends": ["尹天仇", "阿星"],
"cars": [
{"brands": "BYD", "max_speed": 180},
{"brands": "Audi", "max_speed": 280},
{"brands": "Benz", "max_speed": 320}
]
}
try:
with open("data.json", "w",encoding="utf-8") as f:
json.dump(mydict, f)
except IOError as e:
print(e)
print("保存数据完成")
if __name__ "__main__":
main()
json模块四个重要的函数
- dump 将Python对象按照JSON格式序列化到文件中
- dumps 将Python对象处理成JSON格式的字符串
- load 将文件中的JSON数据反序列化成对象
- loads 将字符串的内容反序列化成Python对象
序列化和反序列化
“序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换为可以存储或传输的形式,这样在需要的时候能够恢复到原先的状态,而且通过序列化的数据重新获取字节时,可以利用这些字节来产生原始对象的副本(拷贝)。与这个过程相反的动作,即从一系列字节中提取数据结构的操作,就是反序列化(deserialization)”。
目前绝大多数网络数据服务(或称之为网络API)都是基于HTTP协议提供JSON格式的数据,关于HTTP协议的相关知识,可以看看阮一峰老师的《HTTP协议入门》,如果想了解国内的网络数据服务,可以看看聚合数据和阿凡达数据等网站,国外的可以看看{API}Search网站。下面的例子演示了如何使用requests模块(封装得足够好的第三方网络访问模块)访问网络API获取国内新闻,如何通过json模块解析JSON数据并显示新闻标题,这个例子使用了天行数据提供的国内新闻数据接口,其中的APIKey需要自己到该网站申请。
import requests
import json
def main():
resp = requests.get('http://api.tianapi.com/guonei/?key=APIKey&num=10')
data_model = json.loads(resp.text)
for news in data_model['newslist']:
print(news['title'])
if __name__ == '__main__':
main()
在Python中要实现序列化和反序列化除了使用json模块之外,还可以使用pickle和shelve模块,但是这两个模块是使用特有的序列化协议来序列化数据,因此序列化后的数据只能被Python识别