Day-21 基礎模組2 pickle shelve json configparser
一、pickle(重點)
pickle用起來很簡單,說白了,就是把我們的python物件寫入到檔案中的一種解決方案,但是寫入到檔案的是bytes,所以這東西不是給別人看的,是給機器看的。
import pickle class Cat: def __init__(self, name ,age): self.name = name self.age = age def catchMouse(self): print(self.name, "抓老鼠") c = Cat("jerry", 18) bs = pickle.dumps(c) #序列化一個物件 print(bs) #一堆二進位制,看不懂 cc = pickle.loads(bs) #把二進位制反序列化成我們的物件 cc.catchMouse() #jerry 抓老鼠
pickle中的dumps可以序列化一個物件,loads可以反序列化一個物件,我們使用dump還可以直接把一個物件寫入到檔案中
# f = open("cat", mode="wb") # pickle.dump(c, f) # 寫入到檔案中 # f.close() f = open("cat", mode="rb") cc = pickle.load(f) # 從檔案中讀取物件cc.catchMouse()
這裡記住, 不能一行一行的讀. 那真的要寫入或者讀取多個內容怎麼辦? 很簡單. 裝list裡. 然後讀取和寫入都用list
lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("alpha", 21)] f = open("cat", mode="wb") pickle.dump(lst, f) f = open("cat", mode="rb") ll = pickle.load(f) for el in ll: el.catchMouse()
記住一點, pickle序列化的內容是二進位制的內容(bytes) 不是給人看的.
二、shelve
shelve提供python的持久化操作. 什麼叫持久化操作呢? 說白話,就是把資料寫到硬碟上。在操作shelve的時候非常的像操作一個字典. 這個東西到後期. 就像redis差不多.
import shelve shelf = shelve.open("sylar") # shelf["jay"] = "周杰倫" print(shelf['jay']) shelf.close()
感覺到了麼. 這個鬼東西和字典差不多. 只不過你的字典是一個檔案. 接下來, 我們儲存一些複雜的資料
s = shelve.open("sylar") # s["jay"] = {"name":"周杰倫", "age":18, "hobby":"哄小孩"} print(s['jay']) s.close()
但是, 有坑
s = shelve.open("sylar") s['jay']['name'] = "胡辣湯" # 嘗試改變字典中的資料 s.close() s = shelve.open("sylar") print(s['jay']) # 並沒有改變 s.close()
解決方案
s = shelve.open("sylar", writeback=True) s['jay']['name'] = "胡辣湯" # 嘗試改變字典中的資料 s.close() s = shelve.open("sylar") print(s['jay']) # 改變了. s.close()
writeback=True可以動態的把我們修改的資訊寫入到檔案中. 而且這個鬼東西還可以刪除資料. 就像字典一樣. 上一波操作
s = shelve.open("sylar", writeback=True) del s['jay'] s.close() s = shelve.open("sylar") print(s['jay']) # 報錯了, 沒有了 s.close() s = shelve.open("sylar", writeback=True) s['jay'] = "周杰倫" s['wlj'] = "王力巨集" s.close() s = shelve.open("sylar") for k in s: # 像字典一樣遍歷 print(k) print(s.keys()) # 拿到所有key的集合 for k in s.keys(): print(k) for k, v in s.items(): # 像字典一樣操作 print(k, v) s.close()
綜上shelve就當成字典來⽤就⾏了. 它比redis還簡單.......
三、json(重點)
json是我們前後端互動的樞紐. 相當於程式設計界的普通話. 大家溝通都用json. 為什麼這樣呢? 因為json的語法格式可以完美的表示出一個物件. 那什麼是json: json全稱javascript object notation. 翻譯過來叫js物件簡譜.
如何把字典轉化成我們的json格式的字串呢?很簡單, 上程式碼.
import json dic = {"a": "女王", "b": "蘿莉", "c": "小清新"} s = json.dumps(dic) # 把字典轉化成json字串 print(s) # {"a": "\u5973\u738b", "b": "\u841d\u8389", "c":"\u5c0f\u6e05\u65b0"}
結果很不友好啊. 那如何處理中文呢? 在dumps的時候給出另一個引數ensure_ascii=False就可以了
import json dic = {"a": "女王", "b": "蘿莉", "c": "小清新"} s = json.dumps(dic, ensure_ascii=False) # 把字典轉化成json字串 print(s) # {"a": "女王", "b": "蘿莉", "c": "小清新"}
搞定了. 接下來. 前端給你傳遞資訊了. 你要把前端傳遞過來的json字串轉化成字典.
import json s = '{"a": "女王", "b": "蘿莉", "c": "小清新"}' dic = json.loads(s) print(type(dic), dic)
搞定. 是不是很簡單. 以上兩個程式碼要求. 記住, 理解, 背會
json也可以像pickle一樣把序列化的結果寫入到檔案中.
dic = {"a": "女王", "b": "蘿莉", "c": "小清新"} f = open("test.json", mode="w", encoding="utf-8") json.dump(dic, f, ensure_ascii=False) # 把物件打散成json寫入到檔案中 f.close()
同樣也可以從也件中讀取一個json
f = open("test.json", mode="r", encoding="utf-8") dic = json.load(f) f.close() print(dic)
注意. 我們可以向同一個檔案中寫入多個json串. 但是讀不行
import json lst = [{"a": 1}, {"b": 2}, {"c": 3}] f = open("test.json", mode="w", encoding="utf-8") for el in lst: json.dump(el, f) f.close()
注意, 此時檔案中的內容是一行內容.
{"a": 1}{"b": 2}{"c": 3}
這在讀取的時候是無法正常讀取的. 那如何解決呢? 兩套方案. 方案一. 把所有的內容準備好統進行寫入和讀取. 但這樣處理, 如果資料量小還好. 資料量大的話, 就不夠友好了. 方案二. 不用dump. 改用dumps和loads. 對每一行分別進行處理.
import json lst = [{"a": 1}, {"b": 2}, {"c": 3}] # 寫入 f = open("test.json", mode="w", encoding="utf-8") for el in lst: s = json.dumps(el, ensure_ascii=True) + "\n" f.write(s) f.close() # 讀取 f = open("test.json", mode="r", encoding="utf-8") for line in f: dic = json.loads(line.strip()) print(dic) f.close()
四、configparser
該模組適用於配置檔案的格式與windows ini檔案類似,可以包含一個或多個節(section)每個節可以有多個引數(鍵=值). 首先, 我們先看一個xxx伺服器的配置檔案
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no
我們用configparser就可以對這樣的檔案進行處理.首先, 是初始化
import configparser config = configparser.ConfigParser() config['DEFAULT'] = { "sleep": 1000, "session-time-out": 30, "user-alive": 999999 } config['TEST-DB'] = { "db_ip": "192.168.17.189", "port": "3306", "u_name": "root", "u_pwd": "123456" } config['168-DB'] = { "db_ip": "152.163.18.168", "port": "3306", "u_name": "root", "u_pwd": "123456" } config['173-DB'] = { "db_ip": "152.163.18.173", "port": "3306", "u_name": "root", "u_pwd": "123456" } f = open("db.ini", mode="w") config.write(f) # 寫入檔案 f.flush() f.close()
讀取檔案資訊:
config = configparser.ConfigParser() config.read("db.ini") # 讀取檔案 print(config.sections()) # 獲取到section. 章節...DEFAULT是給每個章節都配備的資訊 print(config.get("DEFAULT", "SESSION-TIME-OUT")) # 從xxx章節中讀取到xxx資訊 # 也可以像字典一樣操作 print(config["TEST-DB"]['DB_IP']) print(config["173-DB"]["db_ip"]) for k in config['168-DB']: print(k) for k, v in config["168-DB"].items(): print(k, v) print(config.options('168-DB')) # 同for迴圈,找到'168-DB'下所有鍵 print(config.items('168-DB')) #找到'168-DB'下所有鍵值對 print(config.get('168-DB','db_ip')) # 152.163.18.168 get方法Section下的key對應的value
增刪改操作:
# 先讀取. 然後修改. 最後寫回檔案 config = configparser.ConfigParser() config.read("db.ini") # 讀取檔案 # 新增一個章節 # config.add_section("189-DB") # config["189-DB"] = { # "db_ip": "167.76.22.189", # "port": "3306", # "u_name": "root", # "u_pwd": "123456" # } # 修改資訊 config.set("168-DB", "db_ip", "10.10.10.168") # 刪除章節 config.remove_section("173-DB") # 刪除元素資訊 config.remove_option("168-DB", "u_name") # 寫回檔案 config.write(open("db.ini", mode="w"))