1. 程式人生 > >Day-21 基礎模組2 pickle shelve json configparser

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"))