從零開始學Python:第22課-Python標準庫初探

千鋒Python唐小強發表於2020-08-13

Python語言最可愛的地方在於它的標準庫和三方庫實在是太豐富了,日常開發工作中的很多工都可以透過這些標準庫或者三方庫直接解決。下面我們先介紹Python標準庫中的一些常用模組,後面的課程中再陸陸續續為大家介紹 Python常用三方庫的用途和用法

從零開始學Python:第22課-Python標準庫初探

base64 - Base64編解碼模組

Base64是一種基於64個可列印字元來表示二進位制資料的方法。由於log2 64=6 ,所以Base64以6個位元(二進位制位,可以表示0或1)為一個單元,每個單元對應一個可列印字元。對於3位元組(24位元)的二進位制資料,我們可以將其處理成對應於4個Base64單元,即3個位元組可由4個可列印字元來表示。Base64編碼可用來作為電子郵件的傳輸編碼,也可以用於其他需要將二進位制資料轉成文字字元的場景,這使得在XML、JSON、YAML這些文字資料格式中傳輸二進位制內容成為可能。在Base64中的可列印字元包括A-Z、a-z、0-9,這裡一共是62個字元,另外兩個可列印符號通常是+和/,=用於在Base64編碼最後進行補位。

Python標準庫中的base64模組提供了b64encode和b64decode兩個函式,專門用於實現Base64的編碼和解碼,下面演示了在 Python的互動式環境中執行這兩個函式的效果。


>>> 
import base64

>>>
>>> content = 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
>>> base64.b64encode(content.encode())
b'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
>>> content = b'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
>>> base64.b64decode(content).decode()
'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'

collections - 容器資料型別模組

collections模組提供了諸多非常好用的資料結構,主要包括:

  • namedtuple:命令元組,它是一個類工廠,接受型別的名稱和屬性列表來建立一個類。
  • deque:雙端佇列,是列表的替代實現。Python中的列表底層是基於陣列來實現的,而deque底層是雙向連結串列,因此當你需要在頭尾新增和刪除元素是,deque會表現出更好的效能,漸近時間複雜度為O(1。
  • Counter:dict的子類,鍵是元素,值是元素的計數,它的most_common()方法可以幫助我們獲取出現頻率最高的元素。Counter和dict的繼承關係我認為是值得商榷的,按照CARP原則,Counter跟dict的關係應該設計為關聯關係更為合理。
  • OrderedDict:dict的子類,它記錄了鍵值對插入的順序,看起來既有字典的行為,也有連結串列的行為。
  • defaultdict:類似於字典型別,但是可以透過預設的工廠函式來獲得鍵對應的預設值,相比字典中的setdefault()方法,這種做法更加高效。

下面是在 Python互動式環境中使用namedtuple建立puke牌類的例子。


>>> 
from collections 
import namedtuple

>>>
>>> Card = namedtuple( 'Card', ( 'suite', 'face'))
>>> card1 = Card( '紅桃', 5)
>>> card2 = Card( '草花', 9)
>>> card1
Card(suite= '紅桃', face= 5)
>>> card2
Card(suite= '草花', face= 9)
>>> print( f' {card1.suite} {card1.face}')
紅桃 5
>>> print( f' {card2.suite} {card2.face}')
草花 9

下面是使用Counter類統計列表中出現次數最多的三個元素的例子。


from collections 
import Counter


words = [
    'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
    'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around',
    'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes',
    'look', 'into', 'my', 'eyes', "you're", 'under'
]
counter = Counter(words)
# 列印words列表中出現頻率最高的3個元素及其出現次數
for elem, count in counter.most_common(3):
   print(elem, count)

hashlib - 雜湊函式模組

雜湊函式又稱雜湊演算法或雜湊函式,是一種為已有的資料建立“數字指紋”(雜湊摘要)的方法。雜湊函式把資料壓縮成摘要,對於相同的輸入,雜湊函式可以生成相同的摘要(數字指紋),需要注意的是這個過程並不可逆(不能透過摘要計算出輸入的內容)。一個優質的雜湊函式能夠為不同的輸入生成不同的摘要,出現雜湊衝突(不同的輸入產生相同的摘要)的機率極低,MD5、SHA家族就是這類好的雜湊函式。

說明:在2011年的時候,RFC 6151中已經禁止將MD5用作金鑰雜湊訊息認證碼,這個問題不在我們討論的範圍內。

Python標準庫的hashlib模組提供了對雜湊函式的封裝,透過使用md5、sha1、sha256等類,我們可以輕鬆的生成“數字指紋”。舉一個簡單的例子,使用者註冊時我們希望在資料庫中儲存使用者的密碼,很顯然我們不能將使用者密碼直接儲存在資料庫中,這樣可能會導致使用者隱私的洩露,所以在資料庫中儲存使用者密碼時,通常都會將密碼的“指紋”儲存起來,使用者登入時透過雜湊函式計算密碼的“指紋”再進行匹配來判斷使用者登入是否成功。


import hashlib


# 計算字串 "123456"的MD5摘要
print(hashlib.md5( '123456'.encode()).hexdigest())

# 計算檔案 "Python-3.7.1.tar.xz"的MD5摘要
hasher = hashlib.md5()
with open( 'Python-3.7.1.tar.xz', 'rb') as file:
    data = file.read( 512)
    while data:
       hasher.update( data)
        data = file.read( 512)
print(hasher.hexdigest())

說明:很多網站在下載連結的旁邊都提供了雜湊摘要,完成檔案下載後,我們可以計算該檔案的雜湊摘要並檢查它與網站上提供的雜湊摘要是否一致(指紋比對)。如果計算出的雜湊摘要與網站提供的並不一致,很有可能是下載出錯或該檔案在傳輸過程中已經被篡改,這時候就不應該直接使用這個檔案。上面的程式碼用到了Python中的檔案操作,具體的內容在下一課中有詳細的講解。

heapq - 堆排序模組

heapq模組實現了堆排序演算法,如果希望使用堆排序,尤其是要解決 TopK問題(從序列中找到K個最大或最小元素),直接使用該模組即可,程式碼如下所示。


import 
heapq


list1 = [34, 25 , 12 , 99 , 87 , 63 , 58 , 78 , 88 , 92 ]
# 找出列表中最大的三個元素
print(heapq.nlargest(3, list1))
# 找出列表中最小的三個元素
print(heapq.nsmallest(3, list1))

list2 = [
    {'name': 'IBM' , 'shares': 100 , 'price': 91.1 },
    {'name': 'AAPL' , 'shares': 50 , 'price': 543.22 },
    {'name': 'FB' , 'shares': 200 , 'price': 21.09 },
    {'name': 'HPQ' , 'shares': 35 , 'price': 31.75 },
    {'name': 'YHOO' , 'shares': 45 , 'price': 16.35 },
    {'name': 'ACME' , 'shares': 75 , 'price': 115.65 }
]
# 找出價格最高的三隻股票
print(heapq.nlargest(3, list2, key=lambda x: x['price']))
# 找出持有數量最高的三隻股票
print(heapq.nlargest(3, list2, key=lambda x: x['shares']))

itertools - 迭代工具模組

itertools可以幫助我們生成各種各樣的迭代器,大家可以看看下面的例子。

import itertools


# 產生ABCD的全排列
for value in itertools.permutations( 'ABCD'):
    print(value)

# 產生ABCDE的五選三組合
for value in itertools.combinations( 'ABCDE', 3):
    print(value)

# 產生ABCD和 123的笛卡爾積
for value in itertools.product( 'ABCD', '123'):
    print(value)

# 產生ABC的無限迴圈序列
it = itertools.cycle(( 'A', 'B', 'C'))
print( next(it))
print( next(it))
print( next(it))
print( next(it))

random - 隨機數和隨機抽樣模組

這個模組我們之前已經用過很多次了,生成隨機數、實現隨機亂序和隨機抽樣,下面是常用函式的列表。

  • getrandbits(k):返回具有k個隨機位元位的整數。
  • randrange(start, stop[, step]):從range(start, stop, step) 返回一個隨機選擇的元素,但實際上並沒有構建一個range物件。
  • randint(a, b):返回隨機整數N滿足a <= N <= b,相當於randrange(a, b+1)。
  • choice(seq):從非空序列seq返回一個隨機元素。 如果seq為空,則引發IndexError。
  • choices(population, weight=None, *, cum_weights=None, k=1):從population中選擇替換,返回大小為k的元素列表。 如果population為空,則引發IndexError。
  • shuffle(x[, random]):將序列x隨機打亂位置。
  • sample(population, k):返回從總體序列或集合中選擇k個不重複元素構造的列表,用於無重複的隨機抽樣。
  • random():返回[0.0, 1.0)範圍內的下一個隨機浮點數。
  • expovariate(lambd):指數分佈。
  • gammavariate(alpha, beta):伽瑪分佈。
  • gauss(mu, sigma) / normalvariate(mu, sigma):正態分佈。
  • paretovariate(alpha):帕累託分佈。
  • weibullvariate(alpha, beta):威布林分佈。

os.path - 路徑操作相關模組

os.path模組封裝了操作路徑的工具函式,如果程式中需要對檔案路徑做拼接、拆分、獲取以及獲取檔案的存在性和其他屬性,這個模組將會非常有幫助,下面為大家羅列一些常用的函式。

  • dirname(path):返回路徑path的目錄名稱。
  • exists(path):如果path指向一個已存在的路徑或已開啟的檔案描述符,返回 True。
  • getatime(path) / getmtime(path) / getctime(path):返回path的最後訪問時間/最後修改時間/建立時間。
  • getsize(path):返回path的大小,以位元組為單位。如果該檔案不存在或不可訪問,則丟擲OSError異常。
  • isfile(path):如果path是普通檔案,則返回 True。
  • isdir(path):如果path是目錄(資料夾),則返回True。
  • join(path, *paths):合理地拼接一個或多個路徑部分。返回值是path和paths所有值的連線,每個非空部分後面都緊跟一個目錄分隔符 (os.sep),除了最後一部分。這意味著如果最後一部分為空,則結果將以分隔符結尾。如果引數中某個部分是絕對路徑,則絕對路徑前的路徑都將被丟棄,並從絕對路徑部分開始連線。
  • splitext(path):將路徑path拆分為一對,即(root, ext),使得root + ext == path,其中ext為空或以英文句點開頭,且最多包含一個句點。

uuid - UUID生成模組

uuid模組可以幫助我們生成全域性唯一識別符號(Universal Unique IDentity)。該模組提供了四個用於生成UUID的函式,分別是:

  • uuid1():由MAC地址、當前時間戳、隨機數生成,可以保證全球範圍內的唯一性。
  • uuid3(namespace, name):透過計算名稱空間和名字的MD5雜湊摘要(“指紋”)值得到,保證了同一名稱空間中不同名字的唯一性,和不同名稱空間的唯一性,但同一名稱空間的同一名字會生成相同的UUID。
  • uuid4():由偽隨機數生成UUID,有一定的重複機率,該機率可以計算出來。
  • uuid5():演算法與uuid3相同,只不過雜湊函式用SHA-1取代了MD5。

由於uuid4存在機率型重複,那麼在真正需要全域性唯一識別符號的地方最好不用使用它。在分散式環境下,uuid1是很好的選擇,因為它能夠保證生成ID的全域性唯一性。下面是在 Python互動式環境中使用uuid1函式生成全域性唯一識別符號的例子。


>>> 
import uuid

>>> uuid.uuid1().hex
'622a8334baab11eaaa9c60f81da8d840'
>>> uuid.uuid1().hex
'62b066debaab11eaaa9c60f81da8d840'
>>> uuid.uuid1().hex
'642c0db0baab11eaaa9c60f81da8d840'

簡單的總結

Python標準庫中有大量的模組,日常開發中有很多常見的任務在Python標準庫中都有封裝好的函式或類可供使用,這也是Python這門語言最可愛的地方。

夥伴們不清楚的地方可以留言哦,需要相關教程的,也可以私我!



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69923331/viewspace-2711549/,如需轉載,請註明出處,否則將追究法律責任。

相關文章