Python內(nèi)置json實(shí)現(xiàn)數(shù)據(jù)本地持久化詳解
四個(gè)json函數(shù)
函數(shù) | |
---|---|
json.load() | 將本地json數(shù)據(jù)文件讀取出來,并以列表形式返回從文件對(duì)象中讀取 JSON 格式的字符串,并將其反序列化為 Python 對(duì)象 |
json.loads() | 將 JSON 格式的字符串反序列化為 Python 對(duì)象 |
json.dump() | 將 Python 對(duì)象序列化為 JSON 格式的字符串,并將其寫入文件對(duì)象。 |
json.dumps() | 將 Python 對(duì)象序列化為 JSON 格式的字符串 |
將數(shù)據(jù)以json文件保存在本地的方式
使用file.open()
實(shí)例數(shù)據(jù)
class Person: name = None age = None def __init__(self, name, age): self.name = name self.age = age person1 = Person("Alice", 30) person2 = Person("Bob", 25) person3 = Person("Charlie", 35) person4 = Person("David", 28) person5 = Person("Eve", 32) persons = [person1, person2, person3, person4, person5] person_list = [person.__dict__ for person in persons] print(person_list) ''' [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}, {'name': 'David', 'age': 28}, {'name': 'Eve', 'age': 32}] <class 'list'> 返回的是一個(gè)列表 '''
object.__dict__
object.__dict__
是 Python 中的一個(gè)特殊屬性,用于存儲(chǔ)對(duì)象的實(shí)例屬性。每個(gè) Python 對(duì)象都有一個(gè) __dict__
屬性,它是一個(gè)字典,包含了對(duì)象的所有實(shí)例屬性及其對(duì)應(yīng)的值
將對(duì)象的數(shù)據(jù)保存到j(luò)son中,需要先使用對(duì)象.__dict__
將每一個(gè)對(duì)象的字典形式取出(使用列表推導(dǎo)式),在將每一個(gè)對(duì)象的字典形式保存在列表中,將列表保存在json文件中
data_list = [person.__dict__ for person in persons] # 列表推導(dǎo)式
保存數(shù)據(jù)
def load_data(): with open(data_file, 'r', encoding='utf-8') as file: return json.load(file)
讀取數(shù)據(jù)
def save_data(persons): with open(data_file, 'w', encoding='utf-8') as file: json.dump([person.__dict__ for person in persons], file, indent=2)
注意事項(xiàng)
open() 函數(shù)自動(dòng)創(chuàng)建文件:
'r' 模式(只讀模式)下,如果文件不存在,會(huì)直接拋出 FileNotFoundError,不會(huì)自動(dòng)創(chuàng)建文件。
只有使用'w'(寫入模式)或 'a'(追加模式)時(shí),如果文件不存在,才會(huì)自動(dòng)創(chuàng)建。
實(shí)際案例:
class HouseService: house_list = [] data_file = os.path.join(os.path.dirname(__file__), 'house_data.json') def __init__(self): self.load_data() if not self.house_list: house1 = House('1', 'lihua', '123456', '鄭州中原區(qū)', 800, '未出租') house2 = House('2', 'jack', '123452', '鄭州市二七區(qū)', 900, '未出租') self.house_list.append(house1) self.house_list.append(house2) self.save_data() # 加載房屋數(shù)據(jù) def load_data(self): try: with open(self.data_file, 'r', encoding='utf-8') as file: data = json.load(file) self.house_list = [House(**house) for house in data] except FileNotFoundError: self.house_list = [] # 保存房屋數(shù)據(jù) def save_data(self): with open(self.data_file, 'w', encoding='utf-8') as file: json.dump([house.__dict__ for house in self.house_list], file, ensure_ascii=False, indent=4)
在此案例下,load_data()
函數(shù)如果不采用異常捕獲的話,且文件夾中并沒有house_data.json
文件時(shí),系統(tǒng)將直接拋出異常,當(dāng)捕獲異常之后,并初始化數(shù)據(jù)列表,程序可以繼續(xù)向下進(jìn)行,來到save_data()
保存數(shù)據(jù),并自動(dòng)創(chuàng)建json文件
所以在開發(fā)過程中,編寫保存房屋數(shù)據(jù)時(shí),注意異常捕獲
追加數(shù)據(jù)
如果有新的數(shù)據(jù)需要保存,不能直接使用mode='a'
, 'a'
模式追加寫入,會(huì)導(dǎo)致JSON文件變成多個(gè)獨(dú)立對(duì)象而不是有效數(shù)組,新追加的數(shù)據(jù)會(huì)直接保存在[]外面
[{...}, {...}] // 原始數(shù)據(jù) {...} // 新追加數(shù)據(jù)(格式錯(cuò)誤)
所以要向json文件中追加數(shù)據(jù),需要用到一下方法:
采用讀取→修改→覆蓋寫入的模式(而不是直接追加)
使用'w'模式保證每次寫入完整的JSON數(shù)組結(jié)構(gòu)
import os import json # 示例數(shù)據(jù) data = { "name": "Alice", "age": 30, "skills": ["Python", "Docker"], "is_active": True } data_dile = os.path.join(os.path.dirname(__file__), 'person_data.json') def save_data(data): with open(data_dile, 'w', encoding='utf-8') as file: json.dump(data, file, indent=2) def load_data(): with open(data_dile, 'r', encoding='utf-8') as file: data = json.load(file) return data exist_data = load_data() # 取出現(xiàn)有數(shù)據(jù) print(type(exist_data)) # <class 'list'> exist_data.append(data) # 想列表中追加數(shù)據(jù) save_data(exist_data) # 保存追加過數(shù)據(jù)后的列表
到此這篇關(guān)于Python內(nèi)置json實(shí)現(xiàn)數(shù)據(jù)本地持久化詳解的文章就介紹到這了,更多相關(guān)Python數(shù)據(jù)本地持久化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python+django+mysql開發(fā)實(shí)戰(zhàn)(附demo)
本文主要介紹了python+django+mysql開發(fā)實(shí)戰(zhàn)(附demo),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01pygame實(shí)現(xiàn)井字棋之第二步邏輯實(shí)現(xiàn)
這篇文章主要介紹了pygame實(shí)現(xiàn)井字棋之第二步邏輯實(shí)現(xiàn),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05Python從列表推導(dǎo)到zip()函數(shù)的5種技巧總結(jié)
在本篇文章里小編給大家整理的是關(guān)于Python從列表推導(dǎo)到zip()函數(shù)的5種技巧的相關(guān)知識(shí)點(diǎn)和代碼,需要的朋友們參考學(xué)習(xí)下。2019-10-10ConvNeXt實(shí)戰(zhàn)之實(shí)現(xiàn)植物幼苗分類
ConvNeXts由標(biāo)準(zhǔn)ConvNet模塊構(gòu)建,在準(zhǔn)確性和可擴(kuò)展性方面與 Transformer競(jìng)爭(zhēng),實(shí)現(xiàn)87.8% ImageNet top-1 準(zhǔn)確率,在 COCO 檢測(cè)和 ADE20K 分割方面優(yōu)于 Swin Transformers。本文將利用ConvNeXt實(shí)現(xiàn)植物幼苗分類,需要的可以參考一下2022-01-01