day12-內置模塊學習(三)

個人博客呀,從之前的預習變成了複習了,複習的東西尚未寫完,哎python

今日目錄算法

1.序列化模塊json

2.加密模塊安全

3.包的使用網絡

4.random模塊數據結構

5.shutil模塊dom

 

開始今日份總結函數

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 當函數過多了,能夠分模塊文件去管理函數,模塊文件過多,須要將模塊分類,放在一個一個的文件夾內。這個文件夾就叫作包,這樣會使得組織結構更加清晰合理

當咱們導入一個模塊的時候會發生三件事

  1. 建立一個以模塊命名的名稱空間
  2. 執行模塊代碼,模塊裏面的代碼會加載在模塊名命名的名稱空間的內存中
  3. 調用模塊名的名字必須經過模塊名的方式調用

包也是模塊,他是模塊的集合體,導入一個包也會發生三件事

  1. 建立一個以包的命名的名稱空間
  2. 執行包內__iter__文件,將__iter__裏面的代碼塊加載到包名對應的名稱空間
  3. 調用包內的名字必須經過包名.的方式去調用

想要在此文件引用 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()
相關文章
相關標籤/搜索