別讓程式碼愁白頭髮!15 個 Python 函式拯救你的開發生活

Sunzz發表於2024-09-07

在 Python 世界裡,有一些寶藏函式和模組,它們可以讓你程式設計更輕鬆、程式碼更高效。這篇文章將帶你一一認識這些神器,讓你的開發生活瞬間輕鬆不少!

轉載請註明原文地址:https://www.cnblogs.com/Sunzz/p/18402025

1. all - 檢查所有元素是否滿足條件

功能介紹

all 函式用於檢查可迭代物件中的所有元素是否都滿足給定的條件。如果可迭代物件為空,則返回 True

使用示例

  1. 檢查列表中的所有數字是否為正數
    numbers = [1, 2, 3, 4]
    result = all(num > 0 for num in numbers)
    print(result)  # 輸出: True
    
  2. 檢查字串中的所有字元是否為字母
    text = "Hello"
    result = all(char.isalpha() for char in text)
    print(result)  # 輸出: True
    
  3. 檢查字典中所有值是否大於 10
    data = {'a': 11, 'b': 12, 'c': 9}
    result = all(value > 10 for value in data.values())
    print(result)  # 輸出: False
    
    

使用場景

驗證資料完整性:確保所有資料項都符合特定條件。
條件檢查:在執行操作之前驗證資料的有效性。

2.any - 檢查是否有元素滿足條件

功能介紹

any函式用於檢查一個可迭代物件(如列表、元組等)中是否有至少一個元素滿足給定的條件。如果有任意一個元素為 True,則返回 True,否則返回 False。如果可迭代物件為空,則返回 False。

使用示例

  1. 檢查列表中是否有大於 10 的數字

    numbers = [1, 5, 8, 12]
    result = any(num > 10 for num in numbers)
    print(result)  # 輸出: True
    
    
  2. 檢查字串是否包含某個字元

    text = "hello"
    result = any(char == 'h' for char in text)
    print(result)  # 輸出: True
    
    
  3. 檢查字典中是否有值為 None

    data = {'name': 'Alice', 'age': None, 'location': 'NY'}
    result = any(value is None for value in data.values())
    print(result)  # 輸出: True
    
    
  4. 檢查元組中是否包含非零元素

    tup = (0, 0, 1, 0)
    result = any(tup)
    print(result)  # 輸出: True
    
    

使用場景

條件檢查:當你希望在一組資料中驗證是否至少有一個元素滿足某個條件時,any 是一個非常高效的工具。例如,檢查使用者輸入是否符合某些標準,或者列表中是否存在滿足特定條件的值。

users = ['admin', 'guest', 'user1']
if any(user == 'admin' for user in users):
    print("Admin is present")

資料驗證:在處理表單或資料庫時,檢查是否有資料欄位為空或無效。

fields = {'name': 'John', 'email': '', 'age': 30}
if any(value == '' for value in fields.values()):
    print("Some fields are empty!")

快速篩選資料:例如,在資料分析中快速檢視是否有不符合條件的資料項。

data_points = [3.2, 5.6, 0.0, -1.2, 4.8]
if any(x < 0 for x in data_points):
    print("Negative data point found!")

注意事項

any 會在遇到第一個為 True 的元素時立即返回,而不會繼續檢查剩餘的元素,因此在效能方面具有優勢。
any 通常與生成器表示式一起使用,使其能夠處理大型資料集而不消耗過多記憶體。
anyall 是一對非常實用的布林函式,能夠快速簡化許多條件檢查的程式碼邏輯。

3. argparse - 處理命令列引數

功能介紹

argparse 模組用於編寫使用者友好的命令列介面。它允許你定義指令碼可以接收的引數,並自動生成幫助資訊。透過命令列傳遞引數可以讓你的程式更加靈活和易於使用,尤其是在需要傳遞多種不同引數的指令碼中。

使用示例

  1. 處理基本的命令列引數
    import argparse
    
    parser = argparse.ArgumentParser(description="這是一個演示指令碼")
    parser.add_argument('--name', type=str, help='輸入你的名字')
    args = parser.parse_args()
    
    print(f"你好, {args.name}!")
    
    

執行示例:

python script.py --name Alice

輸出:

你好, Alice!
  1. 設定預設值和必選引數
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--age', type=int, required=True, help='輸入你的年齡')
    parser.add_argument('--city', type=str, default='Unknown', help='輸入你所在的城市')
    args = parser.parse_args()
    
    print(f"年齡: {args.age}, 城市: {args.city}")
    
    

執行示例:

python script.py --age 30 --city Beijing

輸出:

年齡: 30, 城市: Beijing
  1. 支援布林值引數
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbose', action='store_true', help='是否輸出詳細資訊')
    args = parser.parse_args()
    
    if args.verbose:
        print("詳細模式已開啟")
    else:
        print("預設模式")
    
    

執行示例:

python script.py --verbose

輸出:

詳細模式已開啟
  1. 處理多個命令列引數
    import argparse
    
    parser = argparse.ArgumentParser(description="計算器程式")
    parser.add_argument('num1', type=int, help="第一個數字")
    parser.add_argument('num2', type=int, help="第二個數字")
    parser.add_argument('--operation', type=str, default='add', choices=['add', 'subtract'], help="選擇操作型別:加法或減法")
    args = parser.parse_args()
    
    if args.operation == 'add':
        result = args.num1 + args.num2
    else:
        result = args.num1 - args.num2
    
    print(f"結果: {result}")
    
    

執行示例:

python script.py 10 5 --operation subtract

輸出:

結果: 5

使用場景

命令列工具開發:如指令碼自動化、系統管理任務、檔案處理指令碼等,方便透過命令列傳遞引數。
資料處理指令碼:透過不同的引數,處理不同的資料檔案或資料來源。
指令碼除錯與測試:透過簡單的命令列引數可以快速切換指令碼的行為(例如詳細模式、測試模式等)。

注意事項

自動生成幫助資訊:argparse 會根據你定義的引數自動生成幫助資訊,幫助使用者瞭解如何使用指令碼。
引數型別:支援多種型別的引數,包括字串、整數、布林值、列表等。
引數驗證:argparse 可以自動驗證引數的型別和合法性,確保輸入有效。

4. collections.Counter - 計數器類

功能介紹

Countercollections 模組中的一個字典子類,主要用於計數,統計可迭代物件中每個元素出現的次數。它將元素作為字典的鍵,次數作為值,並且提供了多個方便的計數操作方法。

使用示例

  1. 統計字串中字元的頻率

    from collections import Counter
    text = "hello world"
    counter = Counter(text)
    print(counter)  # 輸出: Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
    
    
  2. 統計列表中元素的出現次數

    items = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
    counter = Counter(items)
    print(counter)  # 輸出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
    
    
  3. 找出最常見的元素

    counter = Counter(items)
    most_common = counter.most_common(2)
    print(most_common)  # 輸出: [('apple', 3), ('banana', 2)]
    
    
  4. 更新計數器

    counter.update(['banana', 'orange', 'apple'])
    print(counter)  # 輸出: Counter({'apple': 4, 'banana': 3, 'orange': 2})
    
    
  5. 計數器的加減操作

    counter1 = Counter(a=3, b=1)
    counter2 = Counter(a=1, b=2)
    result = counter1 + counter2
    print(result)  # 輸出: Counter({'a': 4, 'b': 3})
    
    result = counter1 - counter2
    print(result)  # 輸出: Counter({'a': 2})
    
    

使用場景

統計字元或詞頻:分析文字中字元或單詞的頻率。
計數元素出現的次數:如統計購物車中物品數量、遊戲中的分數等。
找出最常見的元素:從一組資料中快速找出最常出現的元素。

注意事項

負數計數會被保留,但在使用 most_common 等方法時不會顯示。
可以使用 +、-、&、| 等運算子對多個 Counter 物件進行加減或並集交集操作。

5. collections.defaultdict - 帶預設值的字典

功能介紹

defaultdict 是 Python collections 模組中的一個子類,提供了一個帶預設值的字典。當你訪問一個不存在的鍵時,defaultdict 不會丟擲 KeyError,而是會根據提供的工廠函式自動生成預設值。這使得在處理字典時無需手動檢查鍵是否存在,減少程式碼中的冗餘檢查。

使用示例

  1. 建立一個帶預設值的字典

    from collections import defaultdict
    
    # 預設值為0
    dd = defaultdict(int)
    dd['a'] += 1
    print(dd)  # 輸出: defaultdict(<class 'int'>, {'a': 1})
    
  2. 按字元統計字串中字元出現的次數

    text = "hello world"
    char_count = defaultdict(int)
    for char in text:
        char_count[char] += 1
    print(char_count)  # 輸出: defaultdict(<class 'int'>, {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
    
    
  3. 將列表中的元素按長度進行分組

    words = ["apple", "banana", "pear", "kiwi", "grape"]
    word_groups = defaultdict(list)
    for word in words:
        word_groups[len(word)].append(word)
    print(word_groups)  # 輸出: defaultdict(<class 'list'>, {5: ['apple', 'pear', 'grape'], 6: ['banana'], 4: ['kiwi']})
    
    
  4. 自定義預設工廠函式

    def default_value():
        return "default_value"
    
    dd = defaultdict(default_value)
    print(dd["nonexistent_key"])  # 輸出: "default_value"
    
    
  5. 巢狀使用 defaultdict

    # 建立一個巢狀的預設字典
    nested_dict = defaultdict(lambda: defaultdict(int))
    nested_dict['key1']['subkey'] += 1
    print(nested_dict)  # 輸出: defaultdict(<function <lambda> at 0x...>, {'key1': defaultdict(<class 'int'>, {'subkey': 1})})
    
    

使用場景

避免手動檢查鍵是否存在:在處理計數或聚合操作時,避免頻繁進行鍵存在性檢查。
統計資料:如統計字元出現次數、單詞長度分組、計數等。
簡化巢狀結構:使用巢狀 defaultdict 可以建立多層字典結構,避免逐層初始化。

注意事項

defaultdict 的預設值是透過工廠函式生成的,因此每次訪問缺失鍵時都會呼叫這個工廠函式。
小心使用帶副作用的工廠函式,如檔案操作、網路請求等,因為這些操作會在訪問不存在的鍵時被觸發。

6. dataclasses.dataclass - 輕量級資料類

功能介紹

dataclass 是 Python 3.7 引入的一個裝飾器,用於簡化資料類的建立。它可以自動生成類的初始化方法 (__init__)、表示方法 (__repr__) 等,還可以對比物件的相等性 (__eq__),從而減少手動編寫樣板程式碼。

使用示例

  1. 建立一個簡單的資料類

    from dataclasses import dataclass
    
    @dataclass
    class Person:
        name: str
        age: int
    
    person = Person(name="Alice", age=30)
    print(person)  # 輸出: Person(name='Alice', age=30)
    
    
  2. 設定預設值

    @dataclass
    class Person:
        name: str
        age: int = 25  # 預設年齡為25
    
    person = Person(name="Bob")
    print(person)  # 輸出: Person(name='Bob', age=25)
    
    
  3. 生成物件比較方法

    @dataclass
    class Person:
        name: str
        age: int
    
    person1 = Person(name="Alice", age=30)
    person2 = Person(name="Alice", age=30)
    print(person1 == person2)  # 輸出: True
    
    
  4. 凍結資料類(禁止修改屬性)

    
    @dataclass(frozen=True)
    class Person:
        name: str
        age: int
    
    person = Person(name="Alice", age=30)
    # person.age = 31  # 這行程式碼會丟擲錯誤:FrozenInstanceError
    
    
  5. 處理複雜的資料型別

    from dataclasses import dataclass
    from typing import List
    
    @dataclass
    class Team:
        name: str
        members: List[str]
    
    team = Team(name="Developers", members=["Alice", "Bob", "Charlie"])
    print(team)  # 輸出: Team(name='Developers', members=['Alice', 'Bob', 'Charlie'])
    
    

使用場景

簡化資料類的定義:避免手動編寫 initrepreq 等方法,減少冗餘程式碼。
建立不可變物件:透過凍結類屬性實現不可變性(類似於 namedtuple 的行為)。
資料封裝:在應用中使用資料類封裝業務邏輯和資料結構,如定義使用者、商品、訂單等類。

注意事項

資料類可以透過設定 frozen=True 讓屬性不可變,這使得資料類的例項更接近於 namedtuple。
可以透過 field() 函式為類屬性提供更靈活的控制,例如設定預設值、排除某些欄位不進行比較等。

7. datetime - 處理日期和時間

功能介紹

datetime 模組提供了操作日期和時間的強大工具。它允許你獲取當前日期時間、進行時間運算、格式化日期時間字串等。這個模組是處理時間相關任務的首選,非常適合需要追蹤、計算或展示時間的場景。

datetime 主要有幾個核心物件:

  • datetime.datetime: 表示日期和時間的組合。
  • datetime.date: 僅表示日期(年、月、日)。
  • datetime.time: 僅表示時間(時、分、秒)。
  • datetime.timedelta: 用於時間差運算。

使用示例

  1. 獲取當前日期和時間
    from datetime import datetime
    
    now = datetime.now()
    print(f"當前時間: {now}")
    

輸出:

當前時間: 2024-09-07 15:32:18.123456
  1. 格式化日期和時間
    from datetime import datetime
    
    now = datetime.now()
    formatted_time = now.strftime("%Y-%m-%d %H:%M:%S")
    print(f"格式化後的時間: {formatted_time}")
    
    

輸出:

格式化後的時間: 2024-09-07 15:32:18

strftime 用於根據指定格式將日期時間物件轉換為字串。常見格式說明:
%Y: 四位數的年份,如 2024
%m: 兩位數的月份,如 09
%d: 兩位數的日期,如 07
%H: 兩位數的小時,24 小時制
%M: 兩位數的分鐘
%S: 兩位數的秒

  1. 解析日期字串
    from datetime import datetime
    
    date_str = "2024-09-07 15:32:18"
    date_obj = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
    print(f"解析後的日期物件: {date_obj}")
    
    

輸出:

解析後的日期物件: 2024-09-07 15:32:18

strptime 用於根據指定格式將字串轉換為日期時間物件。
4. 計算時間差

from datetime import datetime, timedelta

now = datetime.now()
future = now + timedelta(days=10)
print(f"10天后的日期: {future}")

輸出:

10天后的日期: 2024-09-17 15:32:18.123456

timedelta 物件用於表示兩個日期或時間之間的差值,可以進行加減法運算。
5. 獲取日期部分或時間部分

from datetime import datetime

now = datetime.now()
print(f"當前日期: {now.date()}")
print(f"當前時間: {now.time()}")

輸出:

當前日期: 2024-09-07
當前時間: 15:32:18.123456

使用場景

日誌記錄:自動生成時間戳,用於記錄系統操作、錯誤報告等。
定時任務:設定延遲、時間間隔的操作,例如自動備份系統。
資料處理:對包含時間戳的資料進行操作,如分析時間序列資料或時間範圍過濾。
時間運算:例如計算某個日期之前或之後的天數、小時數等。

注意事項

datetime.now() 獲取當前時間時精確到微秒。如果不需要微秒,可以使用 .replace(microsecond=0) 來忽略。
timedelta 可以進行時間運算,但對於時區計算,需要結合 pytz 模組進行更復雜的時區管理。

8. functools.lru_cache - 快取函式結果,提升效能

功能介紹

functools.lru_cache 是一個非常有用的裝飾器,它可以快取函式的結果,從而避免對相同輸入的重複計算,提升程式的效能。它適用於那些具有重複計算特性且結果可以被重用的函式,特別是在遞迴或大量重複呼叫的場景下表現尤為出色。

lru_cache 中的 "LRU" 是 "Least Recently Used" 的縮寫,意思是當快取達到指定容量時,最久未使用的快取條目將被清除。

使用示例

  1. 遞迴斐波那契數列計算(使用快取):
    from functools import lru_cache
    
    @lru_cache(maxsize=128)
    def fibonacci(n):
        if n < 2:
            return n
        return fibonacci(n-1) + fibonacci(n-2)
    
    print(fibonacci(100))
    

輸出:

354224848179261915075

在上面的例子中,lru_cache 透過快取前面的計算結果,大大提高了遞迴斐波那契數列的效率。如果沒有快取,每次遞迴都會重複計算之前的結果,效率極低。maxsize 引數指定了快取的大小。

  1. 指定快取大小
    @lru_cache(maxsize=32)  # 快取最近32個呼叫結果
    def compute(x):
        # 假設這是一個很耗時的函式
        return x * x
    
    for i in range(40):
        print(compute(i))
    
    print(compute.cache_info())  # 檢視快取的狀態
    
    

輸出:

CacheInfo(hits=0, misses=40, maxsize=32, currsize=32)

cache_info() 方法可以用來檢視快取的命中次數(hits)、未命中次數(misses)、快取最大容量(maxsize)以及當前快取的條目數(currsize)。

  1. 清除快取
    fibonacci.cache_clear()  # 清除快取
    print(fibonacci.cache_info())  # 輸出快取資訊,確認快取已被清除
    
    

cache_clear() 方法可以手動清空快取,適用於需要重置快取的情況。

  1. 處理複雜計算
    @lru_cache(maxsize=100)
    def slow_function(x, y):
        # 模擬耗時計算
        import time
        time.sleep(2)
        return x + y
    
    # 第一次呼叫會等待2秒
    print(slow_function(1, 2))  # 輸出: 3
    
    # 第二次呼叫將直接使用快取的結果,幾乎瞬時完成
    print(slow_function(1, 2))  # 輸出: 3
    
    

輸出:

3
3

透過快取結果,第二次呼叫相同引數時可以節省大量時間。

使用場景

遞迴演算法最佳化:如斐波那契數列、動態規劃問題等,需要重複計算的函式呼叫。
處理複雜計算:對於需要大量重複計算的函式,透過快取結果可以大大提高效能,如 Web 請求的處理、資料庫查詢結果的快取等。
函式呼叫最佳化:在處理相同輸入時,可以避免重複計算或耗時操作。

注意事項

快取大小管理:maxsize 引數控制快取的最大容量,合理設定該值可以在效能與記憶體使用之間找到平衡。如果設定為 None,則快取大小無限。
避免快取不必要的資料:對於一些引數變化較多的函式,快取可能會佔用大量記憶體,應慎重使用 lru_cache。
快取失效策略:lru_cache 使用的是最近最少使用 (LRU) 策略來移除舊的快取項,因此不會一直保留所有的快取結果。

9. itertools.chain - 將多個可迭代物件串聯起來

功能介紹

itertools.chainitertools 模組中的一個函式,它可以將多個可迭代物件(如列表、元組、集合等)“串聯”成一個單一的迭代器。這樣你可以在遍歷多個可迭代物件時無需巢狀迴圈,從而簡化程式碼結構。

使用示例

  1. 串聯多個列表

    from itertools import chain
    
    list1 = [1, 2, 3]
    list2 = [4, 5, 6]
    result = list(chain(list1, list2))
    print(result)  # 輸出: [1, 2, 3, 4, 5, 6]
    
    
  2. 串聯不同型別的可迭代物件

    list1 = [1, 2, 3]
    tuple1 = (4, 5, 6)
    set1 = {7, 8, 9}
    result = list(chain(list1, tuple1, set1))
    print(result)  # 輸出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    
  3. 串聯多個字串

    str1 = "ABC"
    str2 = "DEF"
    result = list(chain(str1, str2))
    print(result)  # 輸出: ['A', 'B', 'C', 'D', 'E', 'F']
    
    
  4. 合併多層巢狀的迭代器

    nested_list = [[1, 2], [3, 4], [5, 6]]
    result = list(chain.from_iterable(nested_list))
    print(result)  # 輸出: [1, 2, 3, 4, 5, 6]
    
    
  5. 處理生成器

    
    def generator1():
        yield 1
        yield 2
    
    def generator2():
        yield 3
        yield 4
    
    result = list(chain(generator1(), generator2()))
    print(result)  # 輸出: [1, 2, 3, 4]
    
    

使用場景

合併多個資料來源:當你需要遍歷多個可迭代物件時,使用 chain 可以避免多層迴圈。
合併巢狀列表:使用 chain.from_iterable 可以展平巢狀的可迭代物件,方便處理巢狀結構的資料。
簡化程式碼:如果需要對多個列表、生成器等進行統一操作,chain 可以減少冗餘程式碼並提高程式碼的可讀性。

注意事項

itertools.chain 是一個迭代器,不會立刻生成結果,直到你真正遍歷它。因此對於超大資料集,chain 的效能更優,因為它不會一次性載入所有資料到記憶體中。
如果需要串聯巢狀可迭代物件,推薦使用 chain.from_iterable,而不是巢狀 chain 函式呼叫。

10. json - 處理JSON資料的好幫手

功能介紹

json 模組是 Python 用來解析、生成和操作 JSON(JavaScript Object Notation)資料的內建模組。JSON 是一種輕量級的資料交換格式,廣泛用於 Web 應用程式與伺服器之間的資料通訊。透過 json 模組,Python 可以方便地將 JSON 格式的字串解析為 Python 物件,或將 Python 物件序列化為 JSON 格式的字串。

常用的函式包括:

  • json.dumps(): 將 Python 物件轉換為 JSON 字串。
  • json.loads(): 將 JSON 字串解析為 Python 物件。
  • json.dump(): 將 Python 物件寫入檔案,儲存為 JSON 格式。
  • json.load(): 從檔案讀取 JSON 資料並轉換為 Python 物件。

使用示例

  1. 將 Python 物件轉換為 JSON 字串
    import json
    
    data = {'name': 'John', 'age': 30, 'city': 'New York'}
    json_str = json.dumps(data)
    print(json_str)
    
    

輸出:

{"name": "John", "age": 30, "city": "New York"}

這裡將 Python 字典 data 轉換為了 JSON 格式的字串。
2. 將 JSON 字串解析為 Python 物件

json_str = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_str)
print(data['name'])

輸出:

John

透過 json.loads(),我們將 JSON 字串解析回 Python 字典,然後可以訪問其中的資料。
3. 將 JSON 資料寫入檔案

import json

data = {'name': 'Alice', 'age': 25, 'city': 'London'}
with open('data.json', 'w') as file:
    json.dump(data, file)

結果: 這段程式碼會在當前目錄下生成一個 data.json 檔案,內容為:

{
    "name": "Alice",
    "age": 25,
    "city": "London"
}
  1. 從檔案讀取 JSON 資料

    import json
    
    with open('data.json', 'r') as file:
        data = json.load(file)
    print(data)
    
    

輸出:

{'name': 'Alice', 'age': 25, 'city': 'London'}

透過 json.load() 函式,我們從檔案中讀取並解析了 JSON 資料。

  1. 自定義 JSON 序列化和反序列化
    有時候,JSON 不支援某些 Python 物件(如日期時間),我們可以自定義序列化方法:

    import json
    from datetime import datetime
    
    def datetime_serializer(obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        raise TypeError("Type not serializable")
    
    data = {'name': 'Bob', 'timestamp': datetime.now()}
    json_str = json.dumps(data, default=datetime_serializer)
    print(json_str)
    
    

輸出:

{"name": "Bob", "timestamp": "2024-09-07T15:32:18.123456"}

自定義 default 引數可用於處理 JSON 預設不支援的物件型別。

使用場景

Web 開發:將資料以 JSON 格式在前端和後端之間傳輸,例如從 API 獲取資料時常用 JSON 格式。
配置檔案:許多應用程式使用 JSON 檔案來儲存配置資料。
日誌記錄:將系統操作日誌儲存為 JSON 格式,便於分析和處理。
資料序列化:用於儲存和共享 Python 資料結構,如儲存爬蟲資料、機器學習模型引數等。

注意事項

JSON 的資料型別限制:JSON 支援的資料型別包括字串、數字、布林值、陣列、物件和 null,不支援複雜的 Python 物件(如類例項、函式等)。
UTF-8 編碼:json 模組預設使用 UTF-8 編碼,因此可以很好地處理國際化字元。
避免重複資料的寫入:使用 json.dump() 時,一定要小心檔案的開啟模式,確保不會覆蓋重要資料。

11. pickle - 序列化和反序列化物件

功能介紹

pickle 是 Python 標準庫中的一個模組,用於將 Python 物件序列化為位元組流,或將位元組流反序列化為原始物件。這使得物件可以儲存到檔案中或者在網路上傳輸。pickle 支援幾乎所有的 Python 物件,包括複雜的資料結構和自定義物件。

使用示例

  1. 將物件序列化到檔案

    import pickle
    
    data = {'name': 'Alice', 'age': 30, 'city': 'Wonderland'}
    
    # 將物件序列化並寫入檔案
    with open('data.pkl', 'wb') as file:
        pickle.dump(data, file)
    
    
  2. 從檔案反序列化物件

    
    import pickle
    
    # 從檔案讀取並反序列化物件
    with open('data.pkl', 'rb') as file:
        data = pickle.load(file)
    print(data)  # 輸出: {'name': 'Alice', 'age': 30, 'city': 'Wonderland'}
    
    
  3. 將物件序列化為位元組流

    import pickle
    
    data = [1, 2, 3, {'a': 'A', 'b': 'B'}]
    
    # 序列化物件為位元組流
    byte_stream = pickle.dumps(data)
    print(byte_stream)
    
    
  4. 從位元組流反序列化物件

    
    import pickle
    
    byte_stream = b'\x80\x04\x95\x1c\x00\x00\x00\x00\x00\x00\x00\x8c\x04list\x94\x8c\x04\x00\x00\x00\x00\x00\x00\x00\x8c\x03int\x94\x8c\x04\x00\x00\x00\x00\x00\x00\x00\x8c\x03dict\x94\x8c\x03\x00\x00\x00\x00\x00\x00\x00\x8c\x01a\x94\x8c\x01A\x94\x8c\x01b\x94\x8c\x01B\x94\x87\x94\x00\x00\x00\x00\x00\x00\x00'
    
    # 反序列化位元組流為物件
    data = pickle.loads(byte_stream)
    print(data)  # 輸出: [1, 2, 3, {'a': 'A', 'b': 'B'}]
    
    
  5. 序列化自定義物件

    import pickle
    
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __repr__(self):
            return f"Person(name={self.name}, age={self.age})"
    
    person = Person("Bob", 25)
    
    # 將自定義物件序列化到檔案
    with open('person.pkl', 'wb') as file:
        pickle.dump(person, file)
    
    # 從檔案反序列化自定義物件
    with open('person.pkl', 'rb') as file:
        loaded_person = pickle.load(file)
    print(loaded_person)  # 輸出: Person(name=Bob, age=25)
    
    

使用場景

持久化資料:將資料儲存到檔案中,方便在程式重啟後恢復。
物件傳輸:在網路通訊中傳輸 Python 物件,尤其是在分散式系統中。
資料快取:將計算結果快取到檔案中,以便下次快速載入。

注意事項

安全性:反序列化資料時需謹慎,因為 pickle 可以執行任意程式碼,可能導致安全風險。儘量避免從不可信來源載入資料。
相容性:不同版本的 Python 可能不完全相容 pickle 資料,特別是在使用不同 Python 版本時。
效能:序列化和反序列化大物件時,效能可能會受到影響,可以考慮使用其他序列化格式(如 JSON)作為替代。

12. pprint - 格式化列印資料結構

功能介紹

pprint 是 Python 標準庫中的一個模組,提供了格式化列印複雜資料結構的功能。它可以將巢狀的資料結構(如字典、列表、元組等)以更易讀的格式輸出,幫助開發者更好地除錯和檢視資料。

使用示例

  1. 列印巢狀的字典
    from pprint import pprint
    
    data = {
        'name': 'Alice',
        'age': 30,
        'address': {
            'street': '123 Main St',
            'city': 'Wonderland'
        },
        'hobbies': ['reading', 'hiking', 'coding']
    }
    pprint(data)
    
    

輸出:

{'address': {'city': 'Wonderland', 'street': '123 Main St'},
'age': 30,
'hobbies': ['reading', 'hiking', 'coding'],
'name': 'Alice'}
  1. 列印長列表
    
    from pprint import pprint
    
    long_list = list(range(100))
    pprint(long_list)
    
    

輸出:

[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, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
  1. 列印帶有自定義縮排的字典
    from pprint import pprint
    
    data = {
        'name': 'Bob',
        'age': 25,
        'address': {
            'street': '456 Elm St',
            'city': 'Metropolis'
        },
        'hobbies': ['cycling', 'cooking', 'traveling']
    }
    pprint(data, indent=2)
    
    

輸出:

{'name': 'Bob',
'age': 25,
'address': {'street': '456 Elm St', 'city': 'Metropolis'},
'hobbies': ['cycling', 'cooking', 'traveling']}
  1. 列印帶有自定義寬度的列表
    from pprint import pprint
    
    data = list(range(50))
    pprint(data, width=40)
    
    

輸出:

[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, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
  1. 使用 pprint 列印自定義物件
    from pprint import pprint
    
    class Person:
        def __init__(self, name, age, address):
            self.name = name
            self.age = age
            self.address = address
    
        def __repr__(self):
            return f"Person(name={self.name}, age={self.age}, address={self.address})"
    
    person = Person("Charlie", 40, "789 Maple St")
    pprint(person)
    
    

輸出:

Person(name=Charlie, age=40, address=789 Maple St)

使用場景

除錯複雜資料結構:在除錯程式時,使用 pprint 可以更清晰地檢視複雜的巢狀資料結構。
資料分析:列印大型資料集合時,格式化輸出有助於快速理解資料內容和結構。
日誌記錄:在記錄日誌時,使用 pprint 可以使資料更易讀,幫助分析問題。

注意事項

pprint 適用於較為複雜的資料結構,簡單的資料結構使用普通的 print 更為高效。
調整 indent 和 width 引數可以控制輸出的格式和可讀性,根據具體需求選擇合適的設定。

13. re - 正規表示式處理利器

功能介紹

re 模組是 Python 中用來處理正規表示式的模組,提供了強大的字串匹配、查詢、替換等功能。正規表示式是一種匹配字串的模式,透過特定的規則,可以用於處理複雜的文字操作,比如提取資料、驗證輸入格式等。

常用的函式包括:

  • re.match(): 從字串的開頭進行匹配。
  • re.search(): 在整個字串中搜尋第一個匹配項。
  • re.findall(): 找到所有與正規表示式匹配的子串。
  • re.sub(): 使用另一個字串替換匹配到的部分。
  • re.split(): 根據正規表示式分割字串。

使用示例

  1. 簡單匹配
    import re
    
    pattern = r'\d+'  # 匹配一個或多個數字
    result = re.match(pattern, '123abc')
    print(result.group())  # 輸出: 123
    
    

re.match 函式從字串的開頭開始匹配。上例中匹配到了字串開頭的數字 123。

  1. 查詢字串中的第一個匹配項
    result = re.search(r'[a-z]+', '123abc456')
    print(result.group())  # 輸出: abc
    
    

re.search 在整個字串中搜尋,返回第一個符合模式的子串。
3. 查詢所有匹配項

result = re.findall(r'\d+', '123abc456def789')
print(result)  # 輸出: ['123', '456', '789']

re.findall 返回所有與模式匹配的部分,以列表形式給出。
4. 替換匹配到的字串

result = re.sub(r'\d+', '#', '123abc456')
print(result)  # 輸出: #abc#

re.sub 使用 # 替換所有匹配的數字部分。
5. 根據正規表示式分割字串

result = re.split(r'\d+', 'abc123def456ghi')
print(result)  # 輸出: ['abc', 'def', 'ghi']

re.split 按照正規表示式中的數字進行分割,結果是一個列表。
6. 使用命名組提取特定資訊

pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, 'Date: 2024-09-07')
print(match.group('year'))  # 輸出: 2024
print(match.group('month'))  # 輸出: 09
print(match.group('day'))  # 輸出: 07

命名組可以給每個匹配的子串起名字,從而方便後續的提取。

使用場景

表單驗證:驗證電子郵件、電話號碼、郵政編碼等格式。

email = 'example@domain.com'
pattern = r'^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$'
if re.match(pattern, email):
    print("Valid email")
else:
    print("Invalid email")

資料提取:從文字中提取特定格式的資料,例如日期、時間、金額等。

text = 'Total cost is $123.45, and date is 2024-09-07.'
cost = re.search(r'\$\d+\.\d{2}', text).group()
print(cost)  # 輸出: $123.45

日誌分析:分析系統日誌,提取時間戳、IP 地址、錯誤資訊等。

log = '192.168.0.1 - - [07/Sep/2024:14:55:36] "GET /index.html HTTP/1.1" 200 2326'
ip = re.search(r'\d+\.\d+\.\d+\.\d+', log).group()
print(ip)  # 輸出: 192.168.0.1

字串替換和格式化:透過模式匹配,快速進行復雜的文字替換或格式化。

text = 'User ID: 1234, Date: 2024-09-07'
new_text = re.sub(r'\d+', '[ID]', text)
print(new_text)  # 輸出: User ID: [ID], Date: [ID]

注意事項

貪婪與非貪婪匹配:預設情況下,正規表示式是貪婪的,會盡可能多地匹配字元。可以透過 ? 實現非貪婪匹配,例如 r'<.?>'。
避免過於複雜的正則:雖然正規表示式功能強大,但複雜的表示式可能難以維護,建議保持簡潔。
跳脫字元:某些字元在正規表示式中有特殊含義(如 .、
、+ 等),使用它們時需要透過 \ 進行轉義。

14. timeit.timeit - 測量程式碼執行時間

功能介紹

timeit.timeit 是 Python 標準庫中的一個函式,用於精確測量小段程式碼的執行時間。它特別適合用於效能測試,能夠準確地計算出程式碼塊的執行時間,並提供有關程式碼執行效率的有價值資訊。

使用示例

  1. 測量簡單程式碼的執行時間

    import timeit
    
    # 測量一行程式碼的執行時間
    execution_time = timeit.timeit('x = sum(range(100))', number=10000)
    print(f"Execution time: {execution_time} seconds")
    
    
  2. 測量函式的執行時間

    import timeit
    
    def test_function():
        return sum(range(100))
    
    execution_time = timeit.timeit(test_function, number=10000)
    print(f"Execution time: {execution_time} seconds")
    
    
  3. 使用 timeit 測量程式碼塊的執行時間

    import timeit
    
    code_to_test = '''
    result = 0
    for i in range(1000):
        result += i
    '''
    
    execution_time = timeit.timeit(code_to_test, number=1000)
    print(f"Execution time: {execution_time} seconds")
    
    
  4. 使用 timeit 測量帶有 setup 程式碼的執行時間

    import timeit
    
    setup_code = '''
    import random
    data = [random.randint(1, 100) for _ in range(1000)]
    '''
    
    test_code = '''
    sorted_data = sorted(data)
    '''
    
    execution_time = timeit.timeit(test_code, setup=setup_code, number=1000)
    print(f"Execution time: {execution_time} seconds")
    
    
  5. 測量程式碼效能的複雜場景

    import timeit
    
    setup_code = '''
    import numpy as np
    data = np.random.rand(1000)
    '''
    
    test_code = '''
    mean_value = np.mean(data)
    '''
    
    execution_time = timeit.timeit(test_code, setup=setup_code, number=1000)
    print(f"Execution time: {execution_time} seconds")
    
    

使用場景

效能分析:評估程式碼段或函式的效能,找出潛在的效能瓶頸。
最佳化程式碼:透過測量不同演算法或實現的執行時間,選擇最優的解決方案。
比較不同實現:在對比不同的實現方式時,使用 timeit 可以提供準確的執行時間資料。

注意事項

測量粒度:timeit 主要用於測量小段程式碼的效能,測量時間過長的程式碼段可能需要調整 number 引數。
環境一致性:為了獲得準確的效能測試結果,確保測量程式碼在相同的環境和條件下執行。
測量多次:建議執行多次測量以獲得更穩定的結果,避免偶發性的效能波動。

15. uuid - 生成唯一識別符號

功能介紹

uuid 是 Python 標準庫中的一個模組,用於生成全球唯一識別符號(UUID)。UUID 是一種標準格式的識別符號,廣泛用於需要唯一標識的場景,如資料庫主鍵、分散式系統中的物件標識等。uuid 模組支援多種生成 UUID 的方法,包括基於時間、隨機數和雜湊值等方式。

使用示例

  1. 生成一個基於時間的 UUID
    import uuid
    
    uuid1 = uuid.uuid1()
    print(f"UUID1: {uuid1}")
    

輸出:
UUID1: 123e4567-e89b-12d3-a456-426614174000

  1. 生成一個基於隨機數的 UUID
    import uuid
    
    uuid4 = uuid.uuid4()
    print(f"UUID4: {uuid4}")
    
    

輸出:

UUID4: 9d6d8a0a-1e2b-4f8c-8c0d-15e16529d37e
  1. 生成一個基於名稱的 UUID
    import uuid
    
    namespace = uuid.NAMESPACE_DNS
    name = "example.com"
    uuid3 = uuid.uuid3(namespace, name)
    print(f"UUID3: {uuid3}")
    
    

輸出:

UUID3: 5d5c4b37-1c73-3b3d-bc8c-616c98a6a3d3
  1. 生成一個基於 SHA-1 雜湊值的 UUID
    import uuid
    
    namespace = uuid.NAMESPACE_URL
    name = "http://example.com"
    uuid5 = uuid.uuid5(namespace, name)
    print(f"UUID5: {uuid5}")
    

輸出:

UUID5: 9b3f7e1d-f9b0-5d8b-9141-fb8b571f4f67
  1. 將 UUID 轉換為字串
    import uuid
    
    uuid_obj = uuid.uuid4()
    uuid_str = str(uuid_obj)
    print(f"UUID as string: {uuid_str}")
    
    

輸出:

UUID as string: 2d5b44b8-4a0f-4f3d-a2b4-3c6e1f7f6a3b

使用場景

唯一識別符號:生成唯一的識別符號用於資料庫主鍵、會話標識、檔名等。
分散式系統:在分散式系統中生成唯一的 ID,以確保不同節點生成的識別符號不會重複。
資料追蹤:生成唯一的識別符號用於跟蹤資料或物件的生命週期,例如在日誌記錄中標識事件。

注意事項

UUID 的版本:uuid 模組提供了不同版本的 UUID(如 UUID1、UUID4、UUID3 和 UUID5),選擇適合的版本根據實際需求。
效能考慮:對於大量生成 UUID 的應用,考慮選擇合適的 UUID 版本來最佳化效能。例如,UUID4 基於隨機數,生成速度較快,但可能會有衝突風險;UUID1 基於時間和節點資訊,生成速度較慢,但唯一性更高。
格式一致性:UUID 在不同應用和系統之間傳遞時,需要確保格式一致,通常使用標準的字串格式進行傳遞。

相關文章