1. 程式人生 > 其它 >Python基本內建模組

Python基本內建模組

一 數學相關模組

數學相關模組
  math模組

decimal模組

 

random模組

 

secrets模組

 

應用場景 和計算相關

Decimal可以避免浮點型計算結果丟失精度的問題

偽隨機數模組,並非真正的隨機

希望得到更加安全的隨機數。python3.6版本以後,secrets模組用於生成高度加密的隨機數,適於管理密碼、賬戶驗證、安全憑據及機密資料。

常見方法

ceil(x) 對數值x進行向上取整

floor(x) 對數值x進行向下取整

from decimal import getcontext, Decimal

random() 產生一個[0.0, 1.0) 範圍內的隨機浮點數

randint(a, b) 產生指定範圍[a,b]內的隨機整數

choice(seq) 從序列seq中隨機抽取一個成員

choices(seq, k) 從序列seq中隨機抽取k個成員,以列表格式返回結果

shuffle() 打亂列表中成員的排列循序

sample(s, k) 打亂一個不可變序列並隨機提取k個成員返回新列表

 

import secrets, string 
例項

"""ceil 向上取整"""
print(math.ceil(1.9)) # 2
print(math.ceil(-1.9)) # -1

# 如果小數位精度太小,會出現精度丟失問題
print(math.ceil(1.000000000000000111)) # 1
print(math.ceil(-1.9999999999999999)) # -2

 

from decimal import getcontext, Decimal
"""如果要float浮點型別與decimal型別進行計算,則必須統一型別"""
"""所以Decimal裡面的引數,務必是數字組成的字串。"""
num = 0.1111
getcontext().prec= 3 #設定數字的精度
res = Decimal(str(num))+Decimal('0.111')-Decimal('0.2')
print(res,type(res)) #0.022 <class 'decimal.Decimal'>
import random
seq = "abdcef"
print(random.choice(seq)) #e
print(random.choices(seq, k=2)) #['d', 'b']

"""shuffle 打亂排列循序"""
seq = ["A", "B", "C", "D", "E", "F"]
random.shuffle(seq)
print(seq)#['D', 'E', 'C', 'B', 'A', 'F']

"""打亂一個不可變序列並隨機提取k個成員返回新列表"""
s = "ABCDEFG"
data = random.sample(s, k=len(s))
print(data) #['B', 'E', 'D', 'C', 'A', 'F', 'G']
ret = "".join(data)
print(ret) # BEDCAFG
import secrets, string
"""生成指定長度的高強度密碼串(字母數字組成,包含至少一個小寫字母,至少一個大寫字母以及至少三個數字)"""
def genstr(size):
# 密碼有大小寫字母,數字,特殊符號組成
characters = string.ascii_letters + string.digits +string.punctuation
# ecure_password = ""
# for i in range(size):
# ecure_password += secrets.choice(characters)
# return ecure_password
while True:
password = "".join(secrets.choice(characters) for i in range(size))
if (any(c.islower() for c in password)
and any(c.isupper() for c in password)
and sum(c.isdigit() for c in password) >= 3
and any(c in string.punctuation for c in password)):
break
return password

ret = genstr(8)
print(ret) #+w@B"+6j
"""生成安全Token(令牌),適用於密碼重置、密保 URL 等應用場景"""
# 十六進位制隨機文字字串組成的token
print(secrets.token_hex(2)) #c5fe
# www.qq.com?token=令牌字串
# 安全的URL隨機文字字串
print(secrets.token_urlsafe(4))#zsrt1w

二 時間日期模組

時間日期相關模組
  時間模組time  日期時間模組datetime  日曆模組calendar
應用場景 轉化日期格式
datatime模組是python內建的加強版time模組,提供更多關於日期(date)、時間(time)、日期時間(datetime)、時間差(timedelta)、時區資訊(timezone)等操作  關於年月周幾的操作
常見方法

time() 獲取本地時間戳,精度在微秒級別

sleep(seconds) 程式睡眠等待指定秒數(seconds=秒)

perf_counter() 效能計數器,用於計算程式執行的總秒數,從程式碼第一行開始從0計時。

process_time() 效能計算器,用於計算程式運行當前程序時的總秒數,不計算time.sleep()耗時。

timezone 獲取當前時區與中時區的時間差。東加西減

首都北京是東八區(CST,UTC/GMT+8), 日本東京是東九區(JST,UTC/GMT+9), 美國紐約是西五區(UTC/GMT-5)。

datetime 日期時間物件,常用的屬性有hour, minute, second, microsecond

timedelta 時間差,即兩個時間點之間的距離或長度

 

monthcalendar(year, month) 按指定年月返回列表格式的日曆資訊,左起週一 
常用操作
import time
'''time模組中時間表現的格式主要有3種格式:時間戳,時間元組,格式化時間'''
"""time() 獲取當前時間戳"""
timestamp = time.time()
print(f"timestamp={timestamp}") # timestamp=1649323220.1235719
"""根據指定時間戳->本地時間字串"""
str_time = time.ctime(1649323220.1235719)#Thu Apr 7 17:20:20 2022
print(str_time)
"""perf_counter() 或 process_counter效能計數器"""
t1 = time.perf_counter()
t11 = time.process_time()
s = 0
for i in range(100000):
s+=i
time.sleep(2)
t2 = time.perf_counter()
t22 = time.process_time()
print(f"{t2-t1=}")#t2-t1=2.01480739
print(f"{t22-t11=}")#t22-t11=0.011088
"""時間元祖->時間戳"""
time_tuple = (2022,4,7,17,20,20,3,97,0)
timestamp = time.mktime(time_tuple)
print(timestamp) #1649323220.0
"""時間戳->時間元祖"""
#timestamp = time.localtime()#獲取本地時間元組
time_tuple = time.localtime(1649323220.1235719)
print(time_tuple)#time.struct_time(tm_year=2022..
"""時間戳->時間元祖"""
#gmt = time.gmtime()#獲取UTC(世界標準時間/GMT)的時間元組
gmt = time.gmtime(1649323220.1235719)
print(gmt)#time.struct_time(tm_year=2022..

"""時間元組->本地時間字串"""
#str_time = time.asctime()#獲取本地時間字串
time_tuple = (2022,4,7,17,20,20,3,97,0)
str_time = time.asctime(time_tuple)
print(str_time)#Thu Apr 7 17:33:24 2022

"""格式化當前日期時間"""
ts = time.strftime("%Y-%m-%d %H:%M:%S") #格式化當前日期時間
print(ts)#2022-04-07 18:02:15
'''格式化日期->元組'''
# 從複雜文字中提取時間,文字內容和格式化字串要匹配一致,不能缺少字元。
dt = "今年是2022年,2月22號22點22分22秒:宜婚嫁"
format = "今年是%Y年,%m月%d號%H點%M分%S秒:宜婚嫁"
tuple_time = time.strptime(dt, format)
# 時間元祖->格式化日期時間
str_time = time.strftime("%Y-%m-%d %H:%M:%S", tuple_time)
print(str_time)#2022-02-22 22:22:22
#指定秒時間戳->格式化日期時間
ts = 1645539742.456123
dt = time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(ts))
print(dt)#2022-02-22 22:22:22 CST

datetime.datetime方法

now(tz=None)獲取當前本地系統時間的datetime物件,可指定時區 YYYY-mm-dd HH:MM:SS.ffffff

fromtimestamp(t, tz=None) 通過時間戳t獲取datetime物件,可指定時區 YYYY-mm-dd HH:MM:SS

strptime(date_string, format) 對字串date_string按format格式化字串轉成datetime物件 YYYY-mm-dd HH:MM:SS

strftime(fmt) 對datetime物件根據fmt格式化轉成字串 YYYY-mm-dd HH:MM:SS

from datetime import datetime
'''datetime.datetime'''
"""通過now獲取當前本地系統時間的datetime物件"""
now = datetime.now()
print(now, type(now))#2022-04-07 19:47:27.687748 <class 'datetime.datetime'>
"""通過時間戳->datetime物件"""
dt1 = datetime.fromtimestamp(1649323220)
print(dt1)#2022-04-07 17:20:20
"""日期時間字串->datetime物件"""
dt = datetime.strptime("2022-02-22 12:21:21","%Y-%m-%d %H:%M:%S")
print(dt, type(dt)) # 2022-02-22 12:21:21 <class 'datetime.datetime'>
# 獲取對應的時間戳
print(dt.timestamp()) # 1645503681.0
"""將datetime物件->日期時間字串"""
fdt = now.strftime("%Y-%m-%d %H:%M:%S")
print(fdt,type(fdt)) # 2022-04-07 19:53:25 <class 'str'>
"""datetime物件,不僅支援比較,也支援數學運算,數學運算的結果是一個時間差物件(timedelta)"""
# 例如:有個清明節親子郊遊活動,活動報名截止時間是:2022-04-10 00:00:00,根據當前時間,得到剩餘的報名時間
now = datetime.now()
end = datetime.strptime("2022-04-10 00:00:00", "%Y-%m-%d %H:%M:%S")
td = end - now
print(td, type(td)) # 2 days, 4:00:33.114001 <class 'datetime.timedelta'>
print(td.days, td.seconds) # 2 14433 2天14433秒
print(td.total_seconds()) # 187233.114001 總秒數

datetime.timedelta:時間差或時間距離

from datetime import timedelta
"""
# 建立一個時間差物件
timedelta(
days=天,
seconds=秒,
microseconds=微秒,
milliseconds=毫秒,
minutes=分,
hours=時,
weeks=周
)
"""
# 2周的時間差物件
delta = timedelta(weeks=2)
print(delta)#14 days, 0:00:00
# 6.5小時的時間差物件
delta = timedelta(hours=6.5)
print(delta) # 6:30:00

delta = timedelta(hours=6, minutes=30)
print(delta) # 6:30:00
# 20分15秒的時間差物件
delta = timedelta(minutes=20, seconds=15)
print(delta) # 0:20:15
'''time物件只支援比較操作,date、datetime等物件支援任意比較與加減運算操作,timedelta物件支援所有操作。'''
"""計算當前時間距離過去某個時間的逝去時間"""
# 如果當前時間是2022-03-02 22:11:29,那麼小紅看到了小明在2022-01-02 12:30:00釋出的一個微信動態距離當前時間過去多久了?
dt1 = datetime.datetime.strptime("2022-01-02 12:30:00", "%Y-%m-%d %H:%M:%S")
dt2 = datetime.datetime.strptime("2022-03-02 22:11:29", "%Y-%m-%d %H:%M:%S")
# # 當前時間 - 過去時間
delta = dt2 - dt1
print(delta) # 59 days, 9:41:29
"""獲取指定年月的資訊列表 (年份,月份) 左起週一"""
import calendar
ret = calendar.monthcalendar(2022, 10)
print(ret)
# [
# [0, 0, 0, 0, 0, 1, 2],
# [3, 4, 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14, 15, 16],
# [17, 18, 19, 20, 21, 22, 23],
# [24, 25, 26, 27, 28, 29, 30],
# [31, 0, 0, 0, 0, 0, 0]
# ]

附:

三 資料轉換模組

在資料儲存和讀取過程中,一般需要資料轉換,因為不管網路傳輸也好,還是儲存資料到檔案也罷,都只支援儲存字串或者二進位制bytes型別資料,因此很多時候,針對python中如列表,元組,字典等資料型別,我們都需要進行格式轉換。

# 序列化
    把不可直接儲存的資料格式變成可儲存資料格式,這個過程就是序列化過程。例如:字典/列表/物件等 => 字串。
# 反序列化
    把可儲存資料格式進行格式還原,這個過程就是反序列化過程。例如:字串還原成字典/列表/物件等。

 

  json模組 pickle模組
說明

是一種輕量級的資料交換格式,易於人閱讀和編寫,常用於不同平臺,不同程式語言之間進行資料傳輸,也常用於對程式設計開發過程中的資料儲存結構或專案配置檔案。

注意:在python中預設就是符合json語法的字串資料。json提供了json字串與其他資料格式之間的序列化和反序列化操作

pickle型別處理資料後的資料是二進位制的,所以對於資料相對於json格式而言,更加緊湊(避免json空行佔空間),效能更好。
語法  
常用操作
例項
import json
"""
json在python中就是字串型別,但是該字串必須符合json語法。
序列化方法
json.dump(obj, fp, indent=None, ensure_ascii=True)
把資料obj轉換格式為json字串並寫入到fp檔案物件中.
如果指定indent,則按長度縮排寫入
如果指定ensure_ascii=True,則對多位元組字元轉換成unicode編碼

json.dumps(obj, indent=None, ensure_ascii=True)
把資料obj轉換格式為json字串
如果指定indent,則按長度縮排寫入
如果指定ensure_ascii=True,則對多位元組字元轉換成unicode編碼
"""

"""寫入資料到json檔案中"""
data = [ {"name": "小明","age":16}, {"name": "王華","age":16}]
fp = open("data.json", "w", encoding="utf-8")
json.dump(data, fp,indent=None, ensure_ascii=False)
"""字典資料轉換json格式字串"""
ret = json.dumps(data,indent=None,ensure_ascii=False)
print(ret)#[{"name": "小明", "age": 16}, {"name": "王華", "age": 16}]
"""從指定檔案中讀取json資料並反序列化"""
data = json.load(open("data.json", "r", encoding="utf-8"))
print(data) # [{'name': '小明', 'age': 16}, {'name': '王華', 'age': 16}]
import pickle
"""序列化一個數據成bytes型別"""
data = {"name": "小明", "age": 13}
ret = pickle.dumps(data)
print(ret) # b'\x80\x04\x95\x1d\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x06\xe5\xb0\x8f\xe6\x98\x8e\x94\x8c\x03age\x94K\ru.'

"""序列化一個數據成bytes型別並寫入指定檔案"""
data = {"name": "小明", "age": 13}
fp = open("1.db", "wb")
pickle.dump(data, fp)
bs=b'\x80\x04\x95\x1d\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x06\xe5\xb0\x8f\xe6\x98\x8e\x94\x8c\x03age\x94K\ru.'
"""把資料反序列化還原格式"""
data = pickle.loads(bs)
print(data, type(data))#{'name': '小明', 'age': 13} <class 'dict'>
"""從指定檔案中讀取資料並反序列化還原格式"""
fp = open("1.db", "rb")
data = pickle.load(fp)
print(data, type(data))#{'name': '小明', 'age': 13} <class 'dict'>
"""pickle的強大之處在於,除了能處理8種基本資料型別以外,針對後面所學的面向物件的資料型別也支援.json僅支援8中基本資料型別轉換"""
 
對比

1. json模組常用於將Python資料轉換為通用的json格式傳遞給其它系統或客戶端,常見於web開發,測試開發,運維開發。
pickle模組常用於將python資料轉換為二進位制格式資料,其序列化之後的資料只能被Python識別,因此只能用於Python系統內部。

2. json序列化後的資料本質上還是字串,所以明文顯示,沒有任何保密性,資料儲存不夠緊湊,存在空間浪費
pickle序列化後的資料是二進位制安全bytes型別,不會明文顯示,具有一定保密性,資料儲存格式緊湊,效能優越。

3. 都是內建模組,所以都有更優的替代方案。
內建的json模組採用C語言編寫,針對於海量資料轉換來說,可以考慮rust開發的rjson模組。
內建的pickle模組,雖然效能較好,但是保密性不足,跨平臺性不足,此時可以考慮採用itsdangrous模組。

四 安全加密模組

雜湊函式:雜湊的本質,就是把任意長度的輸入內容,通過Hash演算法變成不可逆的固定長度的輸出內容(雜湊值,雜湊值,訊息摘要),輸出內容通常用16進位制的字串表示。雜湊的過程是單向的,只有加密,沒有解密。因此你可以把字串進行雜湊獲取雜湊值,但無法從雜湊值逆轉獲取原始字串。常用於資訊加密,開發中的常見應用場景有:資料加密,資料校驗,複雜均衡等。

雜湊碰撞/衝突:兩個不同的資料經過Hash函式計算得到的Hash值一樣。雜湊碰撞無法被完全避免。只能採用各種方法來儘量避免,降低發生的概率。

  hashlib模組 hmac模組
說明 雜湊碰撞無法被完全避免。只能採用各種方法來儘量避免,降低發生的概率。python裡面提供了內建函式hash()。 hmac是一種基於Hash函式和金鑰進行訊息認證的方法,使用hmac函式比標準hash函式更安全,只要改動祕鑰(鹽值),同樣的資料,也會產生不同的雜湊值。
例項
import hashlib
"""md5加密"""
content = "hello world"
md5 = hashlib.md5()
md5.update(content.encode('utf-8')) # hash是基於位元組的,所以需要注意編碼問題
res = md5.hexdigest()
print(f"加密結果:{res}") # 5eb63bbbe01eeed093cb22bb8f5acdc3

"""針對大資料的雜湊計算,可以分多次雜湊,最終的雜湊值是一樣的"""
md5 = hashlib.md5()
md5.update('welcome to python! welcome to beijing!'.encode('utf-8'))
print(md5.hexdigest()) # a1b89154c1e7274499530cd8b3e7f278

md5 = hashlib.md5() #重新定義md5
md5.update('welcome to python! '.encode('utf-8'))
print(md5.hexdigest()) # 891a55288ee147f8d5725bf22c956a9f
md5.update('welcome to beijing!'.encode('utf-8'))# md5.update會將每次字串拼接。若不想拼接,每次使用update之前都要重新定義:md5=hashlib.md5()
print(md5.hexdigest()) # a1b89154c1e7274499530cd8b3e7f278
"""sha1加密.."""
content = "hello world"
sha1 = hashlib.sha1()
sha1.update(content.encode('utf-8'))
res = sha1.hexdigest()
print(f"加密結果:{res}") # 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed

import hmac, secrets, string
message = "123456"
characters = string.ascii_letters + string.digits
key = "".join(secrets.choice(characters) for i in range(6))
h = hmac.new(key.encode(encoding="utf-8"), message.encode(encoding="utf-8"), digestmod='SHA1')
print(h.hexdigest())