常用模块-02
主要內容
1. 什么是序列化
2. pickle
3. shelve
4. json
5. configparser模塊
一. 什么是序列化
在我們存儲數據或者網絡傳輸數據的時候. 需要對我們的對象進行處理. 把對象處理成
方便存儲和傳輸的數據格式. 這個過程叫>>>序列化<<<. 不同的序列列化, 結果也不同. 但是目的是一樣的. 都是為了存儲和傳輸.
在python中存在三種序列化的方案.
◎1. pickle. 可以將我們python中的任意數據類型轉化成bytes并寫入到文件中. 同樣也可以把文件中寫好的bytes轉換回我們python的數據. 這個過程被稱為反序列化
◎2. shelve. 簡單另類的一種序列化的方案. 有點兒類似后面我們學到的redis. 可以作為一種小型的數據庫來使用
◎3. json. 將python中常見的字典, 列表轉化成字符串. 是目前后端數據交互使?用頻率最高的一種數據格式.
二. pickle
pickle用起來很簡單. 說白了. 就是把我們的python對象寫入到文件中的一種解決方案.
但是寫入到文件的是bytes. 所以這東西不是給人看的. 是給機器看的.
# loads 反序列化。 把bytes轉化成對象
# dump 序列化。 把對象轉化成bytes并寫入文件
# load 反序列化。把文件中的bytes讀取。轉化成對象 class Cat:def __init__(self, name, age):self.name = nameself.age = agedef catchMouse(self):print(self.name, "抓老鼠")c = Cat("jerry", 18) bs = pickle.dumps(c) # 序列化一個對象. print(bs) # 一堆二進制. 看不懂cc = pickle.loads(bs) # 把二進制反序列化成我們的對象 cc.catchMouse() # 貓依然是貓. 還可以抓老鼠
★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()★pickle還?支持多個對象的寫出:
#1.lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("alpha", 21)]f = open("cat", mode="wb") for el in lst:pickle.dump(el, f) # 寫入到文件中 f.close()f = open("cat", mode="rb") for i in range(len(lst)):cc = pickle.load(f) # 從文件中讀取對象cc.catchMouse()
#+2.
lst = [Cat("貓1", 10), Cat("貓2", 9), Cat("貓3", 8), Cat("貓4", 7), Cat("貓5", 6)] f = open("pickle-test", mode="wb")
pickle.dump(lst, f)
for el in lst:
pickle.dump(el, f)
f.flush()
f.close()
◆但是這樣寫并不夠好. 因為讀的時候. 并不能知道有多少對象要讀. 這里記住, 不能一行一行的讀. 那真的要寫入或者讀取多個內容怎么辦? 很簡單. 裝lis里. 然后讀取和寫入都用list
lst = [Cat("jerry", 19), Cat("tommy", 20), Cat("alpha", 21)] f = open("pickle-test", mode="rb")while 1:
try:
c1 = pickle.load(f)
c1.catchMouse()
except EOFError:
break
記住一點, pickle序列化的內容是二進制的內容(bytes) 不是給人看的.
三. shelve
shelve提供python的 >>>持久化<<< 操作. 什么叫持久化操作呢? 說白話,就是把數據寫到硬盤上.
在操作shelve的時候非常的像操作一個字典. 這個東西到后期. 就像redis差不多.
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對象簡譜. 很復雜是吧? 來上一段簡單的代碼:
這個不是字典么? 對的. 在python里這叫字典. 但是在javascript里這叫?json. 一模一樣的. 我們發現用這樣的數據結構可以完美的表示出任何對象. 并且可以完整的把對象表示出來. 只要代碼格式比較好. 那可讀性也是很強的. 所以大家公認用這樣一種數據結構作為數據交互的格式. 那在這個東西之前是什么呢? XML.....來看?一段代碼
<?xml version="1.0" encoding="utf-8" ?> <wf><name>汪峰</name><age>18</age><hobby>上頭條</hobby><wife><name>?子怡</name><age>18</age><hobbies><hobby>唱歌</hobby><hobby>跳舞</hobby><hobby>演戲</hobby></hobbies></wife> </wf> 古人(老程序員)都是用這樣的數據進行傳輸的. 先不管這個東西好不好看. 這玩意想要解析.. 那簡直了. 想死的心都有. 所以老版本的xml在維護和處理理上是非常復雜和繁瑣的. 以前的項目幾乎沒有用ajax的.
那json既然這么牛B好?用. 怎么用呢? 注意. 這里又出來一個新問題. 我們的程序是在python?里寫的. 但是前端是在JS那邊來解析json的. 所以. 我們需要把我們程序產生的字典轉化成json格式的json串(字符串). 然后網絡傳輸. 那邊接收到了之后. 它愛怎么處理是它的事情. 那, 如何把字典轉化成我們的json格式的字符串呢?很簡單, 上代碼:
# 結果很不友好啊. 那如何處理中文呢? 在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}]
# 寫入的時候
# 1. 循環
# 2. 用dumps把字典轉化成字符串, 然后手工在后面加一個\n
# 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() # 讀取的時候
# 1. for line in f:
# 2. strip()去掉空白
# 3. loads()變成字典 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)每個節
可以有多個參數(鍵=值).
[[ 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"))
轉載于:https://www.cnblogs.com/presleyren/p/9761028.html
總結
- 上一篇: 设计模式 结构型模式 外观模式(Faca
- 下一篇: Luogu4926 倍杀测量者(二分答案