day18:json模組&time模組&zipfile模組

李博倫發表於2020-07-28

json模組

1.關於json的定義

所有的程式語言都能夠識別的資料格式叫做json,是字串
能夠通過json序列化成字串與如下型別: (int float bool str list tuple dict None)

2.json用法

# 1.dumps和loads是一對,可以序列化字串
dic = {"name":"Libolun","age":81,"classroom":"python31","family":["老爸","老媽","哥哥"]}
# ensure_ascii=False 顯示中文 sort_keys=True 對字典的鍵進行排序
res = json.dumps(dic,ensure_ascii=False,sort_keys=True)
print(res , type(res))

# loads反序列化原來的資料型別
dic = json.loads(res)
print(dic,type(dic))
# 2.dump 和 load 是一對,針對於檔案,把資料序列化後儲存檔案
dic = {"name":"Libolun","age":81,"classroom":"python31","family":["老爸","老媽","哥哥"]}
with open("ceshi0728.json",mode="w",encoding="utf-8") as fp:
    json.dump(dic,fp,ensure_ascii=False)

with open("ceshi0728.json",mode="r",encoding="utf-8") as fp:
    dic = json.load(fp)
    print(dic, type(dic))

3.json和pickle的差別

json可以連續dump,但是不可以連續load

json的連續dump:

"""json 可以連續dump , 但是不能連續load"""
dic1 = {"a":1,"b":2}
dic2 = {"c":3,"d":4}
with open("0728_2.json",mode="w",encoding="utf-8") as fp:
    json.dump(dic1,fp)
    fp.write("\n")
    json.dump(dic2,fp)
    fp.write("\n")

為什麼json不可以連續load呢?

原因:load 在獲取資料時,是一次性拿取所有內容

錯誤的示範:

with open("0728_2.json",mode="r",encoding="utf-8") as fp:
    res = json.load(fp)
    print(res)
'''這樣是不可行的,load會一次性把所有資料都拿出來'''

解決辦法:(for迴圈遍歷fp檔案物件,一個一個loads)

with open("0728_2.json",mode="r",encoding="utf-8") as fp:
    for i in fp:
        dic = json.loads(i)
        print(dic,type(dic))

pickle可以連續dump 也可以連續load 因為pickle在儲存資料的時候會在末尾加上結束符

pickle的連續dump和連續load

"""pickle 可以連續dump 也可以連續load 因為pickle在儲存資料的時候會在末尾加上結束符"""
import pickle
dic1 = {"a":1,"b":2}
dic2 = {"c":3,"d":4}
with open("0728_3.pkl",mode="wb") as fp:
    pickle.dump(dic1,fp)
    pickle.dump(dic2,fp)

with open("0728_3.pkl",mode="rb") as fp:
    dic1 = pickle.load(fp)
    print(dic1 , type(dic1))
    dic2 = pickle.load(fp)
    print(dic2 , type(dic2))

使用pickle獲取檔案當中的所有資料

# try ... except ... 異常處理(用來抑制錯誤的)
"""
try :
    可能報錯的程式碼
except:
    如果報錯執行except這個程式碼塊;
"""
# 獲取檔案當中所有的資料
try:
    with open("0728_3.pkl",mode="rb") as fp:
        while True:
            res = pickle.load(fp)
            print(res)
except:
    pass

json和pickle兩個模組的區別

1.json序列化之後的資料型別是str,所有程式語言都識別,
但是僅限於(int float bool)(str list tuple dict None)
json不能連續load,只能一次性拿出所有資料
2.pickle序列化之後的資料型別是bytes,
所有資料型別都可轉化,但僅限於python之間的儲存傳輸.
pickle可以連續load,多套資料放到同一個檔案中
3.json使用的廣泛性比pickle更強.

time模組

time:時間戳

localtime:時間戳轉化成時間元組

mktime:時間元組轉化成時間戳

ctime:時間戳轉化為時間字串

strftime:時間元組轉化為時間字串

strptime:時間字串轉化為時間元組

# ### time 時間模組
import time

#  localtime -> mktime -> ctime
#  時間元組 -> 時間戳 -> 時間字串

# time() 獲取本地時間戳 (*) res = time.time() print(res) # localtime() 獲取本地時間元組(引數是時間戳,預設當前) (*) res = time.localtime() print(res) """ time.struct_time( tm_year=2020, tm_mon=7, tm_mday=28, tm_hour=10, tm_min=45, tm_sec=9, tm_wday=1, tm_yday=210, tm_isdst=0 ) """ # 指定時間戳,返回時間元組 ttp = 1595904161 res = time.localtime(ttp) print(res) # mktime() 通過時間元組獲取時間戳(引數是時間元組) (*) ttp = (2020,7,28,10,48,30,0,0,0) res = time.mktime(ttp) print(res) # 1595904510 # ctime() 獲取本地時間字串(引數是時間戳,預設當前) (*) res = time.ctime() # 預設以當前時間戳獲取時間字串 print(res) # 指定時間戳 res = time.ctime(1595904161) print(res) # asctime() 通過時間元組獲取時間字串(引數是時間元組)(瞭解) ttp = (2020,7,28,10,54,30,6,0,0) # 不能自動識別周幾. res = time.asctime(ttp) print(res) # 改造辦法 ttp = (2020,7,28,10,54,30,0,0,0) res = time.mktime(ttp) str_time = time.ctime(res) print(str_time) # sleep() 程式睡眠等待 (*) """ time.sleep(2) print("我睡醒了") """ """ strftime => 把時間元組 -> 時間字串 strptime => 把時間字串 -> 時間元組 """ # strftime() 格式化時間字串(格式化字串,時間元祖) (*) # 1.預設按照當前時間做格式化 res = time.strftime("%Y-%m-%d %H:%M:%S") print(res) # 2.指定時間元組,對時間字串格式化 """strftime如果在windows當中出現中文,直接報錯,不能解析,linux 可以支援""" ttp = (2000,10,1,12,12,12,0,0,0) res = time.strftime("%Y-%m-%d %H:%M:%S" , ttp) print(res) # strptime() 將時間字串通過指定格式提取到時間元組中(時間字串,格式化字串) (*) """要求字串不能亂加符號,必須嚴絲合縫.""" strvar = "2020年7月28號11時12分13秒是著名歌星庾澄慶的生日" ttp = time.strptime(strvar,"%Y年%m月%d號%H時%M分%S秒是著名歌星庾澄慶的生日") print(ttp) # perf_counter() 用於計算程式執行的時間 (瞭解) # 記錄開始時間 # startime = time.perf_counter() startime = time.time() for i in range(100000000): pass # 記錄結束時間 # endtime = time.perf_counter() endtime = time.time() print(endtime - startime)

用time模組實現動態進度條

進度條準備工作

import time

# (1) 定義進度條的樣式
'''%-50s讓#號居左顯示且佔50個空位'''
print("[%-50s]" % ("#"))
print("[%-50s]" % ("###############"))
print("[%-50s]" % ("#########################"))

# (2) 讓進度條動起來

strvar = ""
for i in range(50):
    strvar += "#"
    time.sleep(0.1)
    print("\r[%-50s]" % (strvar) , end="" ) # \r的作用:將後面的字元直接拉到當前行行首

實現一個動態的進度條

# (3) 根據檔案的大小,調整進度條的位置
# 假設檔案的大小是 1024000
def progress(percent):    
    # 如果百分比超過了1,說明資料已經接受完畢;
    if percent > 1:
        percent = 1
    
    # 列印對應的#號效果
    strvar = "#" * int(percent * 50) 
    # %% => %
    print("\r[%-50s] %d%%" % (strvar,int(percent * 100)) , end="" )

# 初始化接受的位元組數
recv_size = 0
# 檔案接受總大小 
total_size = 1024000
while recv_size < total_size:
    recv_size += 1024
    # 模擬延遲
    time.sleep(0.01)
    # 計算百分比
    percent = recv_size/total_size #0.001
    # 呼叫進度條函式
    progress(percent)

zipfile模組

# ### zipfile 壓縮模組
import zipfile

# 1.壓縮檔案
# (1) 建立壓縮包
zf = zipfile.ZipFile("1424.zip","w",zipfile.ZIP_DEFLATED)
# (2) 把檔案寫入到壓縮包中
# write(路徑,別名)
zf.write("/bin/cp","cp")
zf.write("bin/chmod","chmod")
# 可以臨時建立一個資料夾在tmp在壓縮包中
zf.write("/bin/df","/tmp/df")
# (3) 關閉壓縮包
zf.close()

# 2.解壓檔案
# (1) 開啟壓縮包
zf = zipfile.ZipFile("1424.zip","r")
# (2) 解壓檔案
# 解壓單個檔案
zf.extract("cp","ceshi1424_2")
# 解壓所有檔案
zf.extractall("ceshi1424")
# (3) 關閉壓縮包
zf.close()

# 3.追加檔案(支援with語法)
with zipfile.ZipFile("1424.zip","a",zipfile.ZIP_DEFLATED) as zf:
    zf.write("/bin/dir","dir")

# 4.檢視壓縮包
with zipfile.ZipFile("1424.zip","r",zipfile.ZIP_DEFLATED) as zf:
    lst = zf.namelist()
    print(lst)

 

相關文章