day12-內建模組學習(三)
我的部落格呀,從以前的預習變成了複習了,複習的東西還沒有寫完,哎
今日目錄
1.序列化模組
2.加密模組
3.包的使用
4.random模組
5.shutil模組
開始今日份總結
1.序列化模組
在學習序列化模組之前,對於網路傳輸以及檔案寫入讀取都是採用將列表,字典這些資料型別轉換成字串進行,這樣怎麼說呢,能完成但是有點太low了,看一下以前的儲存方式
dic = {'test':'test1與test2','test2':[1,2,3],'test3':{'a':'test','b':'test'}} m1 = str(dic) # with open('test','w',encoding='utf-8')as f1:# f1.write(m1) with open('test','r',encoding='utf-8')as f2: ret = f2.read() print(eval(ret)) #列印結果和dic的內容是一致的
不過在轉換成可以使用的內容用的eval所以不建議使用,使用eval如果是黑客給的真實病毒,就會直接執行,有太大的風險,一般不使用。這就匯入後面的序列化模組。
網路傳輸:轉換成bytes,位元組
檔案寫入:bytes,str
什麼是序列化
序列化:將資料(資料結構)----->轉換成特殊的字串(用於網路傳輸)
反序列化:將網路傳輸或者是檔案中特殊的字串轉換為原來的資料結構
以下是python中提供的序列化模組
1.1 json模組
json 序列化模組 是所有語言通用的一種標準(資料轉化格式)。
json可以轉化的資料型別有
# str int bool dict list(tuple)None 注意集合型別是沒辦法轉換的
json的用法就是倆對四個
第一對方法:dumps與loads ,與網路傳輸有關
import json dic ={'a':'bc','b':'cd','c':'ef'} m1 = json.dumps(dic)#將dic轉換成特殊的字元,這個時候就可以將m1寫入檔案with open('test','w',encoding='utf-8')as f1: f1.write(m1) # print(m1) d1 = json.loads(m1)#將特殊的字元轉換成原本格式 print(d1)#將轉換後的字串轉換出來
第二對方法:dump與load方法,與檔案相關
dic ={'a':'bc','b':'cd','c':'ef'} with open('test','w',encoding='utf-8')as f1: json.dump(dic,f1) print('序列化成功!')#檔案寫入成功 with open('test','r',encoding='utf-8')as f2: d1 = json.load(f2) print(d1)#檔案讀取成功
補充方法:對於dump以及load方法每次只能讀取或者寫入一個物件,這個時候就有點尷尬了,這個時候就只能用第一對方法進行對多個物件進行操作了。
dic1 = {'name': '春哥'} dic2 = {'name': '子伍'} dic3 = {'name': '王子'} dic4 = {'name': '女神'} with open('test.json','w',encoding='utf-8') as f1: f1.write(json.dumps(dic1)+'\n') f1.write(json.dumps(dic2)+'\n') f1.write(json.dumps(dic3)+'\n') print('序列化成功!') with open('test.json','a',encoding='utf-8')as f1: f1.write(json.dumps(dic4)) print('yy') with open('test.json','r',encoding='utf-8')as f2: for line in f2: print(json.loads(line))
json的引數
# s = json.dumps(dic,ensure_ascii=False,sort_keys=True,separators=('|',',')) # 序列化過程
# sort_keys 按鍵排序
# ensure_ascii=False 顯示中文
# separators=('|',',') 設定分隔符 沒有意義
總結:
- loads與dumps是,對於網路傳輸,對於多個數據寫入檔案
- load與dumpp是,只能用於單一資料結構寫入檔案
- 如果字典的key為數字,在dumps和loads會將其轉換為字串
1.2 pickle模組
pickle與json一樣是倆對四個用法
dumps與loads 用於網路傳輸,將資料轉換為bytes型別
dic1 = {'name': '春哥'} dic2 = {'name': '子伍'} dic3 = {'name': '王子'} dic4 = {'name': '女神'} import pickle b1 = pickle.dumps(dic1) print(b1) m1 = pickle.loads(b1) print(m1)
dump與load 用於將多個數據寫入檔案,或者是讀取
with open('test.pkl','wb')as f1: pickle.dump(dic1,f1) pickle.dump(dic2,f1) pickle.dump(dic3,f1) pickle.dump(dic4,f1) with open('test.pkl','rb')as f2: ret = pickle.load(f2) ret1 = pickle.load(f2) ret2= pickle.load(f2) ret3= pickle.load(f2) print(ret,ret1,ret2,ret3)
json與pickle的區別
- json是多語言共用,通用性較好,適配str,int,dic,list,tuple,bool以及none
- pickle是python自用的,可以轉換python中的任何資料不過只能寫成bytes型別
1.3 shelve模組
他也是python內建可以序列化的模組,不過他只能對檔案進行操作
import shelve f = shelve.open('shelve_file') f['key'] ={'a':'bc','b':'de','c':'fg'}#直接對檔案控制代碼操作,可以寫入檔案 f.close() f = shelve.open('shelve_file') print(f['key']) f.close()
shelve模組預設是不能對檔案進行修改的,只能刪除,增加,如果加入引數就可以修改了
f = shelve.open('shelve_file',writeback=True)#如果想要對shelve檔案進行操作,必須設定writeback為真 f['key']['new_value'] ='the new message' f.close() f = shelve.open('shleve_file') print(f['key']) f.close()
2.加密模組
加密模組也加摘要演算法,是一堆加密演算法的集合體,一般的用法是給密碼加密或者用作檔案校驗
hashlib:將str型別通過演算法轉換成一串等長度的數字
- 不同的字串,轉換成數字肯定不同
- 相同的字串即使在不同的計算機上使用相同的加密方法,轉換成的數字一定相同
- hashlib加密不可逆,不能破解(如果破解一般都是加鹽)
2.1 MD5加密
2.1.1 普通加密
import hashlib #普通加密 ret = hashlib.md5() ret.update('abc123'.encode('utf-8')) print(ret.hexdigest()) ret.update('aaaaaaaaa'.encode('utf-8')) print(ret.hexdigest()) #結果 e99a18c428cb38d5f260853678922e03 792b419cafa3cca8c85c497ff60910fd #結果都是等長的字串
2.1.2 靜態加鹽加密
ret = hashlib.md5('我們來一場轟轟烈烈的測試'.encode('utf-8'))#這裡就是加鹽,對內容加固定的檔案頭 ret.update('abc123'.encode('utf-8')) print(ret.hexdigest())
2.1.3動態加鹽加密
user_password = input('請輸入你的密碼>>>').strip() ret= hashlib.md5(user_password[::-2].encode('utf-8'))#動態加鹽將字串切割,翻轉取值 ret.update(user_password.encode('utf-8')) print(ret.hexdigest())
2.1.4 小檔案校驗
一般從網路上獲取到檔案,需要對他進行校驗確定他是否傳輸的檔案一致
def check_md5(file): ret = hashlib.md5() with open(file,mode ='rb')as f1: ret.update(f1.read()) return ret.hexdigest() print(check_md5('f1')) print(check_md5('f2')) #結果 b302efd21a6dc13ca8cdb584f1ce1613 b302efd21a6dc13ca8cdb584f1ce1613 #對於原檔案如果將內容文字中間加空號或者其他都會變更,所以一般來確認檔案的正確性
2.1.5大檔案校驗
對於小檔案,直接讀取出來,這樣可行,如果是大檔案呢,一個檔案上T這樣不可能一次性讀出來的,這個時候就需要另外的方式來做校驗
在說明大檔案加密之前有一個測試
#單獨加密 ret = hashlib.md5() ret.update('真相永遠只有一個!'.encode('utf-8')) print(ret.hexdigest()) #連續拼接加密 ret1 = hashlib.md5() ret1.update('真相'.encode('utf-8')) ret1.update('永遠'.encode('utf-8')) ret1.update('只有'.encode('utf-8')) ret1.update('一個!'.encode('utf-8')) print(ret1.hexdigest()) #結果 e269466c88819a19634e4ce95d1f12ae e269466c88819a19634e4ce95d1f12ae
這說明將一個字串分開,最後拼接在一起用相同加密的方式得到的結果是一致的。
def check_md5(file): ret = hashlib.md5() with open(file,mode='rb')as f1: while True: contect = f1.read(1024)#讀取1024位元組 if contect: ret.update(contect) else: break return ret.hexdigest() print(check_md5('f1')) print(check_md5('f2')) #結果 b302efd21a6dc13ca8cdb584f1ce1613 b302efd21a6dc13ca8cdb584f1ce1613
2.2 sha加密
sha的用法其實與md5的用法大同小異,都可以普通加密,帶鹽加密,動態鹽加密,檔案校驗
ret= hashlib.sha1()#不同等級的sha ret.update('123456'.encode('utf-8')) print(ret.hexdigest()) ret1 = hashlib.sha256()#不同等級的sha ret1.update('123456'.encode('utf-8')) print(ret1.hexdigest()) #結果 7c4a8d09ca3762af61e59520943dc26494f8941b 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
就會發現不同等級的sha生成的密碼長度完全不一致
sha與MD5的區別
- MD5比較通用,加密效率快,安全性相對較差
- sha系列,演算法更好,安全性根據密碼等級越高,效率低,耗時長
3.包的使用
3.1 當函式過多了,可以分模組檔案去管理函式,模組檔案過多,需要將模組分類,放在一個一個的資料夾內。這個資料夾就叫做包,這樣會使得組織結構更加清晰合理
當我們匯入一個模組的時候會發生三件事
- 建立一個以模組命名的名稱空間
- 執行模組程式碼,模組裡面的程式碼會載入在模組名命名的名稱空間的記憶體中
- 呼叫模組名的名字必須通過模組名的方式呼叫
包也是模組,他是模組的集合體,匯入一個包也會發生三件事
- 建立一個以包的命名的名稱空間
- 執行包內__iter__檔案,將__iter__裡面的程式碼塊載入到包名對應的名稱空間
- 呼叫包內的名字必須通過包名.的方式去呼叫
想要在此檔案引用 bbb包的m3模組 怎麼做?
第一步 在此檔案 import aaa
第二步:在aaa 的 __init__ 新增 from aaa import bbb
第三步:在bbb 的 __init__ 新增 from aaa.bbb import m3
完成以上三步,那麼我在此執行檔案就可以引用bbb包的m3模組裡面的名字。
aaa.bbb.m3.func3()
# 總結:
# from a.b import c .的左邊一定是個包,import 後面一定一個具體的名字
# 包裡面的__init__ 如果想要引用模組必須是 from ....import ... 不能直接 import
# from a.b.c.d import e.f.g 錯誤
# from a.b.c.d import e
3.2 絕對匯入與相對匯入
絕對匯入:以執行檔案的sys.path為起點開始匯入,稱之為絕對匯入
- 優點:執行檔案與被匯入的模組都可以使用
- 缺點:所有的匯入都是以sys.path為起始點,匯入麻煩
相對匯入:參照當前所在檔案的資料夾為起始開始查詢,稱之為相對匯入
- 符號:.代表當前所在檔案的資料夾,..代表上一級資料夾,…代表上一級上一級的資料夾
- 優點:匯入更加簡單
- 缺點:只能在匯入包中的模組才能使用
4.random模組
random就是一個隨機模組
import random print(random.random())#隨機生成0到1內的小數 print(random.uniform(1,3))#隨機生成1到3內的小數 print(random.randint(1,5))#隨機生成大於等於1,小於等於5的整數 print(random.randrange(1,10,2))#隨機生成1到10內的奇數 print(random.choice(['alex','wusir','日天']))#從列表中隨機選出一個 print(random.sample(['alex','wusir','日天'],2))#從列表中隨機選出多個 li =[1,2,3,4,5] random.shuffle(li)#隨機排列 print(li)
random的應用
#隨機生成一個五字驗證碼 def get_code(): code ='' for i in range(5): num = str(random.randrange(10))#隨機生成一個數字 s = chr(random.randint(97,122))#隨機生成一個小寫字母 s2 = chr(random.randint(65,90))#隨機生成一個大寫字母 msg = random.choice([num,s,s2])#從數字,小寫字母,大寫字母中隨機生成一個 code+=msg print(code) get_code() #結果就一個五位隨機驗證碼
5.shutil模組
import shutil shutil.copyfileobj(open('f2','r'),open('f3','w'))#將f2的內容複製到f3 shutil.copyfile('f2','f2.bak')#將f2檔案複製給bak檔案 shutil.copytree('nb','nbb',ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))#複製一個資料夾 import time import tarfile # 打包檔案 shutil.make_archive('NB1%s' %time.strftime('%Y-%m-%d'),'gztar',root_dir='NB1') # 解壓 t = tarfile.open('NB12019-01-10.tar.gz','r') t.extractall('ttt') t.close()