什麼叫序列化:
將本來的字典、列表等內容轉換成一個字符串的過程就叫作序列化。python
序列化的目的:
1. 以某種存儲形式使自定義對象持久化
2. 將對象從一個地方傳遞到另外一個地方
3. 使程序更具維護性編程
json模塊提供了四個功能:dumps、loads 和 dump、loadjson
import json dic = {'k1':1, 'k2': 2, 'k3': 3} # 序列化 str_dic = json.dumps(dic) # dumps 就是將字典類型轉換爲字符串類型 print(type(str_dic), str_dic) # 執行結果: # <class 'str'> {"k1": 1, "k2": 2, "k3": 3} # 反序列化 dic2 = json.loads(str_dic) # loads 將字符串類型轉換爲字典類型 print(type(dic2), dic2) # 執行結果: # <class 'dict'> {'k2': 2, 'k3': 3, 'k1': 1}
dumps 和 loads 都是在內存中對數據進行操做,並無將序列化後的數據保存到硬盤,程序退出,數據消失。若是要將序列化後的數據永久的保存起來,就須要使用 dump 和 load 來操做:數據結構
import json dic = {'k1':1, 'k2': 2, 'k3': 3} with open('test.json', 'w', encoding='utf-8') as f: json.dump(dic, f) # dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件
with open('test.json', 'r', encoding='utf-8') as f: dic = json.load(f) # load 方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回 print(type(dic), dic) # 執行結果: # <class 'dict'> {'k2': 2, 'k3': 3, 'k1': 1}
當序列化中數據含有中文,建議添加ensure_ascii關鍵字參數來進行序列化,這樣在json文件中依然會顯示中文app
import json dic = {'k1': '中國', 'k2': '美國', 'k3': 3} with open('file.json', 'w', encoding='utf-8') as f: json.dump(dic, f, ensure_ascii=False)
json的格式化輸出:編程語言
import json data = {'username':['小明','baby'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False) print(json_dic2) 執行結果: { "age":16, "sex":"male", "username":[ "小明", "baby" ] }
實例:ide
使用 json 模塊實現用戶註冊登陸:函數
#!/usr/bin/python3 # -*- coding: utf-8 -*- # Author: hkey import json import os def file_oper(file, mode, *args): if mode == 'w': user_info = args[0] with open(file, mode) as f: json.dump(user_info, f) elif mode == 'r': with open(file, mode) as f: user_info = json.load(f) return user_info def regist(file): user_dict = file_oper(file, 'r') while True: username = input('username:').strip() if not username: continue if username in user_dict: print('\033[31;1m錯誤:用戶名已存在.\033[0m') else: break password = input('password:').strip() user_dict[username] = password file_oper(file, 'w', user_dict) print('\033[32;1m註冊成功.\033[0m') def login(file): user_dict = file_oper(file, 'r') while True: username = input('username:').strip() if not username: continue if username not in user_dict: print('\033[32;1m錯誤:用戶名不存在.\033[0m') else: break password = input('password:').strip() if user_dict[username] == password: print('\033[32;1m登陸成功.\033[0m') else: print('\033[31;1m密碼錯誤.\033[0m') def showmenu(): if not os.path.isfile('user_json.db'): file_oper('user.db', 'w', {}) while True: print('1. 註冊\n' '2. 登陸\n' '3. 退出') choice = input('>>>').strip() if choice == '1': regist('user.db') elif choice == '2': login('user.db') elif choice == '3': break else: print('\033[31;1m錯誤:輸入錯誤.\033[0m') if __name__ == '__main__': showmenu()
json模塊和pickle模塊對比:編碼
pickle模塊提供了四個功能:dumps、dump(序列化,存儲)、loads(反序列化,讀)、load(不只能夠序列化字典,列表...能夠把python中任意的數據類型序列化)spa
pickle模塊的使用
dumps import pickle dic = {'k1': 1, 'k2': 2, 'k3': 3} str_dic = pickle.dumps(dic) # 使用dumps進行序列化,序列化後是一串字節類型的數據。 print(str_dic) # 執行結果: # b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01K\x01X\x02\x00\x00\x00k2q\x02K\x02X\x02\x00\x00\x00k3q\x03K\x03u.'
import pickle dic2 = pickle.loads(b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01K\x01X\x02\x00\x00\x00k2q\x02K\x02X\x02\x00\x00\x00k3q\x03K\x03u.') print(dic2) # loads進行反序列化獲得結果 # 執行結果: # {'k2': 2, 'k3': 3, 'k1': 1}
dump 和 load
import pickle l1 = [1, 2, 3, 4, 5, 6, 'hehe', 'haha'] with open('file.json', 'wb') as f: # 這裏必須使用 'wb'進行寫入操做且不用指定字符編碼 pickle.dump(l1, f)
import pickle with open('file.json', 'rb') as f: # 這裏必須使用 'rb'進行讀取操做且不用指定字符編碼 l2 = pickle.load(f) print(l2) # 執行結果: # [1, 2, 3, 4, 5, 6, 'hehe', 'haha']
實例:
使用 pickle 模塊實現用戶註冊登陸:
#!/usr/bin/python3 # -*- coding: utf-8 -*- # Author: hkey import pickle import os def file_oper(file, mode, *args): if mode == 'wb': user_info = args[0] with open(file, mode) as f: pickle.dump(user_info, f) elif mode == 'rb': with open(file, mode) as f: user_info = pickle.load(f) return user_info def regist(file, user_dict): while True: username = input('username:').strip() if not username: continue if username in user_dict: print('\033[31;1m錯誤:用戶名已存在.\033[0m') else: break password = input('password:').strip() user_dict[username] = password file_oper(file, 'wb', user_dict) print('\033[32;1m註冊成功.\033[0m') def login(user_dict): while True: username = input('username:').strip() if not username: continue if username not in user_dict: print('\033[32;1m錯誤:用戶名不存在.\033[0m') else: break password = input('password:').strip() if user_dict[username] == password: print('\033[32;1m登陸成功.\033[0m') else: print('\033[31;1m密碼錯誤.\033[0m') def showmenu(): if not os.path.isfile('user.db'): file_oper('user.db', 'wb', {}) user_dict = file_oper('user.db', 'rb') while True: print('1. 註冊\n' '2. 登陸\n' '3. 退出') choice = input('>>>').strip() if choice == '1': regist('user.db', user_dict) elif choice == '2': login(user_dict) elif choice == '3': break else: print('\033[31;1m錯誤:輸入錯誤.\033[0m') if __name__ == '__main__': showmenu()
shelve是一個簡單的數據存儲方案,他只有一個函數就是open(),這個函數接收一個參數就是文件名,而且文件名必須是.bat類型的。而後返回一個shelf對象,能夠簡單的看成一個字典,當你存儲完畢的時候,就調用close函數來關閉。
永久存儲數據
import shelve she = shelve.open('user') she['xiaom'] = ['male', 20] # 字典的形式,添加一個列表 she['xiaom'].append('aaa') # 新增一個元素 she.close() ----------------------------------------- import shelve s = shelve.open('user') print(s['xiaom']) s.close() # 執行結果: # ['male', 20]
在上面的例子中,新增的元素並無持久保存在文件中。
這是因爲shelve在默認狀況下是不會記錄持久化對象的任何修改,因此在shelve.open()時候須要修改默認參數,不然對象的修改不會保存。
回寫模式 (writeback=True)
import shelve she = shelve.open('user', writeback=True) # 開啓回寫模式 she['xiaom'] = ['male', 20] # 字典的形式,添加一個列表 she['xiaom'].append('aaa') # 新增一個元素 she.close() ----------------------------------------- import shelve s = shelve.open('user') print(s['xiaom']) s.close() # 執行結果: # ['male', 20, 'aaa'] # 新增或修改的內容持久化成功
實例:
使用 shelve 模塊實現用戶註冊登陸:
#!/usr/bin/python3 # -*- coding: utf-8 -*- # Author: hkey import shelve, hashlib db = shelve.open('user.db', writeback=True) def regist(): global db while True: username = input('username:').strip() if not username: continue if username in db: print('\033[31;1m錯誤:用戶名已存在.\033[0m') else: break password = input('password:').strip() md5 = hashlib.md5() md5.update(password.encode()) password_md5 = md5.hexdigest() db[username] = {'password': password_md5} def login(): global db username = input('username:').strip() password = input('password:').strip() md5 = hashlib.md5() md5.update(password.encode()) password = md5.hexdigest() if username in db: password_md5 = db[username].get('password') if password == password_md5: print('\033[32;1m登陸成功.\033[0m') def showmenu(): global db while True: print('1. 註冊\n' '2. 登陸\n' '3. 退出') choice = input('>>>').strip() if choice == '1': regist() elif choice == '2': login() elif choice == '3': break else: print('\033[31;1m序號錯誤.\033[0m') db.close() if __name__ == '__main__': showmenu()
json 、 pickle 、 shelve 三個模塊使用場景及對好比下:
在上面三個 用戶註冊登陸 實例中,不難發現使用 shelve 模塊實現思路是最簡單的。