Python小酷庫系列:Munch,用對象的訪問方式訪問dict

Munch,用對象的訪問方式訪問dict

    • 基本使用
      • 1、創建一個 Munch 對象
      • 2、使用字典初始化
      • 3、訪問不存在的字段
      • 4、嵌套結構支持
      • 5、合并操作
      • 6、應用場景說明
    • 進階功能
      • 1、嵌套寫入:創建不存在的子對象
      • 2、序列化(轉回 dict)
      • 3、深度拷貝結構
      • 4、與 JSON 配合:動態數據結構綁定
      • 5、與 Pydantic/配置類組合使用(讀取動態配置)
    • 實現原理
      • 1、繼承自 dict
      • 2、 重寫了 `__getattr__` 和 `__setattr__` 方法
      • 3、`__delattr__` 支持刪除屬性
      • 4、遞歸嵌套(來自 DefaultMunch.fromDict())
    • 編寫一個更高性能的Munch

Munch 是 Python 中一個小巧實用的庫,它將字典(dict)擴展為支持“點操作”的對象訪問方式,即:

data = Munch({"name":"Alice", "age":18})
print(data.name)   # 而不是 data["name"]

它特別適用于配置讀取、JSON 響應處理、動態數據訪問等場景。

基本使用

1、創建一個 Munch 對象

from munch import Munchm = Munch()
m.name = "Alice"
m.age = 30print(m['name'])   # Alice
print(m.name)      # Alice

2、使用字典初始化

user = Munch({'id': 1, 'username': 'bob'})
print(user.username)  # bob

3、訪問不存在的字段

當你訪問一個 Munch 對象中不存在的鍵(屬性) 時,Munch將拋出AttributeError。我們可以通過以下幾種方式安全地訪問Munch 對象的鍵(屬性):
使用 .get() 方法(dict 風格)

print(m.get('age'))           # 輸出 None
print(m.get('age', 0))        # 輸出默認值 0

使用 in 判斷鍵是否存在

if 'age' in m:print(m.age)

使用 DefaultMunch 自動返回默認值(推薦)

from munch import DefaultMunchm = DefaultMunch(None, {"name": "Alice"})print(m.name)   # Alice
print(m.age)    # None(不會報錯)

4、嵌套結構支持

from munch import DefaultMunch
nested = DefaultMunch.fromDict({"user": {"id": 10,"profile": {"email": "user@example.com"}}
})
print(nested.user.profile.email)  # user@example.com

5、合并操作

Munch 可以通過update()方法將另一個Munch示例或字典合并進當前實例:

from munch import Muncha = Munch(foo=1, nested=Munch(x=1, y=2))
b = {"nested": {"y": 20, "z": 30}}a.update(b)
print(a)
# 結果為Munch({'foo': 1, 'nested': {'y': 20, 'z': 30}})

update() 是 淺合并(shallow merge),如果需要遞歸合并,可以這樣手動實現:

def recursive_update(target, source):for key, value in source.items():if key in target and isinstance(target[key], dict) and isinstance(value, dict):recursive_update(target[key], value)else:target[key] = valuea = Munch(foo=1, nested=Munch(x=1, y=2))
b = {"nested": {"y": 20, "z": 30}}recursive_update(a, b)
print(a)
# 輸出Munch({'foo': 1, 'nested': Munch({'x': 1, 'y': 20, 'z': 30})})

6、應用場景說明

Munch 的性能總體上略低于原生 dict,這是因為它在屬性訪問時多了一層 Python 層的函數調用(比如 getattrsetattr 等),但它仍然足夠輕量,適合大多數非性能瓶頸場景。

Munch適合用于:

  • 配置讀取(如 config.json)
  • CPU 密集或低延遲要求的核心路徑
  • 結構化 JSON 響應封裝

不建議將Munch用于:

  • 類型嚴格檢查的項目(除非手動封裝)
  • 數據探索、Jupyter Notebook 腳本開發
  • 內存/性能受限的環境

進階功能

1、嵌套寫入:創建不存在的子對象

nested = DefaultMunch(dict)
nested.user.info.email = "a@example.com"
print(nested)  # {'user': {'info': {'email': 'a@example.com'}}}

2、序列化(轉回 dict)

m = Munch(name="Alice", age=30)
d = m.toDict()
print(type(d))  # dict

3、深度拷貝結構

import copy
m = Munch(a=1, b={"x": 10})
m_copy = copy.deepcopy(m)

4、與 JSON 配合:動態數據結構綁定

import json
from munch import Munchjson_str = '{"user": {"id": 42, "roles": ["admin", "editor"]}}'
m = Munch(json.loads(json_str))
print(m.user.roles)  # ['admin', 'editor']

5、與 Pydantic/配置類組合使用(讀取動態配置)

import yaml
from munch import Munchwith open("config.yaml") as f:config_dict = yaml.safe_load(f)config = Munch(config_dict)
print(config.database.host)

實現原理

Munch 的原理很簡單:它是在 Python 內置的 dict 類的基礎上,通過重寫屬性訪問相關方法,實現了 “點操作”訪問字典內容 的能力。

1、繼承自 dict

class Munch(dict):...

因此,Munch本質上還是一個字典。

2、 重寫了 __getattr____setattr__ 方法

這些方法控制了對象屬性的讀取和設置:

def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(f"'Munch' object has no attribute {key}")def __setattr__(self, key, value):self[key] = value

3、__delattr__ 支持刪除屬性

def __delattr__(self, key):try:del self[key]except KeyError:raise AttributeError(f"'Munch' object has no attribute {key}")

這保證了 del m.attr 與 del m[‘attr’] 效果一致。

4、遞歸嵌套(來自 DefaultMunch.fromDict())

這個功能將嵌套的字典也轉換為 Munch:

@classmethod
def fromDict(cls, d):return cls({k: cls.fromDict(v) if isinstance(v, dict) else v for k, v in d.items()})

編寫一個更高性能的Munch

有了Munch實現原理的理解,接下來我們實現一個輕量級、性能更高的 “點操作字典” 替代方案:DotDict。它模仿了 Munch 的基本行為,但去除了遞歸轉換、類型檢查等附加功能,以提高性能。
dot_dict.pyDotDict完整源碼

class DotDict(dict):"""更快的支持點操作的 dict,不做嵌套轉換。"""def __getattr__(self, key):try:return self[key]except KeyError as e:raise AttributeError(key) from edef __setattr__(self, key, value):self[key] = valuedef __delattr__(self, key):try:del self[key]except KeyError as e:raise AttributeError(key) from e

test_dot_dict.pyDotDict測試示例

data = DotDict(name="Alice", age=30)print(data.name)     # 點操作訪問
print(data['age'])   # 仍可用原生字典方式data.city = "Beijing"
print(data['city'])  # 北京

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80411.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

對稱加密以及非對稱加密

對稱加密和非對稱加密是兩種不同的加密方式,它們在加密原理、密鑰管理、安全性和性能等方面存在區別,以下是具體分析: 加密原理 對稱加密:通信雙方使用同一把密鑰進行加密和解密。就像兩個人共用一把鑰匙,用這把鑰匙鎖…

[JAVAEE]HTTP協議(2.0)

響應報文格式 響應報文格式由首行,響應頭(header),空行,正文(body) 組成 響應報文首行包括 1.版本號 如HTTP/1.1 2.狀態碼(如200) 描述了請求的結果 3.狀態碼描述(如OK) 首行——狀態碼…

Spring Boot 之MCP Server開發全介紹

Spring AI 的 MCP(模型上下文協議,Model Context Protocol)服務器啟動器為在 Spring Boot 應用程序中設置 MCP 服務器提供了自動配置功能。它使得 MCP 服務器功能能夠與 Spring Boot 的自動配置系統實現無縫集成。 MCP 服務器啟動器具備以下特性: MCP 服務器組件的自動配置…

YOLOv8 對象檢測任務的標注、訓練和部署過程

YOLOv8 對象檢測任務的標注、訓練和部署過程 在計算機視覺領域,對象檢測是一項基礎且重要的任務,YOLOv8 作為當前先進的實時對象檢測模型,以其高效性和準確性受到廣泛關注。從數據準備到最終模型部署,整個流程包含多個關鍵環節&a…

電池熱管理CFD解決方案,為新能源汽車筑安全防線

在全球能源結構加速轉型的大背景下,新能源汽車產業異軍突起,成為可持續發展的重要驅動力。而作為新能源汽車 “心臟” 的電池系統,其熱管理技術的優劣,直接決定了車輛的安全性、續航里程和使用壽命。電池在充放電過程中會產生大量…

Redis 數據類型:掌握 NoSQL 的基石

Redis (Remote Dictionary Server) 是一種開源的、內存中的數據結構存儲系統,通常用作數據庫、緩存和消息代理。 它的高性能和豐富的數據類型使其成為現代應用程序開發中不可或缺的一部分。 本文將深入探討 Redis 的核心數據類型,幫助你更好地理解和利用…

MLX-Audio:高效音頻合成的新時代利器

MLX-Audio:高效音頻合成的新時代利器 現代社會的快節奏生活中,對語音技術的需求越來越高。無論是個性化語音助手,還是內容創作者所需的高效音頻生成工具,語音技術都發揮著不可或缺的作用。今天,我們將介紹一個創新的開…

Kafka單機版安裝部署

目錄 1.1、概述1.2、系統環境1.3、ZooKeeper的作用1.4、部署流程1.4.1、下載安裝包1.4.2、解壓文件1.4.3、創建日志目錄1.4.4、配置Kafka1.4.5、啟動Kafka服務1.4.6、啟動成功驗證 1.5、創建Topic測試1.6、消息生產與消費測試1.6.1、啟動生產者1.6.2、啟動消費者 1.1、概述 Kaf…

【C++設計模式之Observer觀察者模式】

Observer觀察者模式 模式定義動機(Motivation)結構(Structure)應用場景一(氣象站)實現步驟1.定義觀察者接口2.定義被觀察者(主題)接口3.實現具體被觀察者對象(氣象站)4.實現具體觀察者(例如:顯示屏)5.main.cpp中使用示例6.輸出結果7. 關鍵點 …

資產月報怎么填?資產月報填報指南

資產月報是企業對固定資產進行定期檢查和管理的重要工具,它能夠幫助管理者了解資產的使用情況、維護狀況和財務狀況,從而為資產的優化配置和決策提供依據。填寫資產月報時,除了填報內容外,還需要注意格式的規范性和數據的準確性。…

UG471 之 SelectIO 邏輯資源

背景 《ug471》介紹了Xilinx 7 系列 SelectIO 的輸入/輸出特性及邏輯資源的相關內容。 第 1 章《SelectIO Resources》介紹了輸出驅動器和輸入接收器的電氣特性,并通過大量實例解析了各類標準接口的實現。 第 2 章《SelectIO Logic Resources》介紹了輸入輸出數據…

C++ 內存泄漏相關

ASAN 參考鏈接 https://blog.csdn.net/wonengguwozai/article/details/129593186https://www.cnblogs.com/greatsql/p/16256926.htmlhttps://zhuanlan.zhihu.com/p/700505587小demo // leak.c #include <stdio.h> #include <stdlib.h> #include <string.h>…

計算人聲錄音后電平的大小(dB SPL->dBFS)

計算人聲錄音后電平的大小 這里筆記記錄一下&#xff0c;怎么計算已知大小的聲音&#xff0c;經過麥克風、聲卡錄制后軟件內錄得的音量電平值。&#xff08;文章最后將計算過程整理為Python代碼&#xff0c;方便復用&#xff09; 假設用正常說話的聲音大小65dB&#xff08;SP…

【MySQL數據庫】C/C++連接數據庫

MySQL要想在C/C下使用&#xff0c;就必須要有 MySQL 提供的頭文件和相關的庫。 在Ubuntu系統上&#xff0c;使用 apt install mysql-server 安裝MySQL服務器后&#xff0c;僅安裝了MySQL數據庫服務本身&#xff0c;并沒有安裝MySQL開發所需的庫和頭文件。因此&#xff0c;在嘗試…

Kubernetes調度策略深度解析:NodeSelector與NodeAffinity的正確打開方式

在Kubernetes集群管理中&#xff0c;如何精準控制Pod的落點&#xff1f;本文將深入解析兩大核心調度策略的差異&#xff0c;并通過生產案例教你做出正確選擇。 一、基礎概念快速理解 1.1 NodeSelector&#xff08;節點選擇器&#xff09; 核心機制&#xff1a;通過標簽硬匹配…

Golang的linux運行環境的安裝與配置

很多新手在學go時&#xff0c;linux下的配置環境一頭霧水&#xff0c;總結下&#xff0c;可供參考&#xff01; --------------------------------------Golang的運行環境的安裝與配置-------------------------------------- 將壓縮包放在/home/tools/下 解壓 tar -zxvf g…

自定義實現elementui的錨點

背景 前不久有個需求&#xff0c;上半部分是el-step步驟條&#xff0c;下半部分是一些文字說明&#xff0c;需要實現點擊步驟條中某個步驟自定義定位到對應部分的文字說明&#xff0c;同時滾動內容區域的時候還要自動選中對應區域的步驟。element-ui-plus的有錨點這個組件&…

Oracle Fusion常用表

模塊表名表描述字段說明sodoo_headers_all銷售訂單頭表sodoo_lines_all銷售訂單行表sodoo_fulfill_lines_all銷售訂單明細行表popo_headers_all采購訂單頭表popo_lines_all采購訂單行表popo_line_locations_all采購訂單分配表popo_distributions_all采購訂單發運表invEGP_SYSTE…

面試常問系列(一)-神經網絡參數初始化-之-softmax

背景 本文內容還是對之前關于面試題transformer的一個延伸&#xff0c;詳細講解一下softmax 面試常問系列(二)-神經網絡參數初始化之自注意力機制-CSDN博客 Softmax函數的梯度特性與輸入值的幅度密切相關&#xff0c;這是Transformer中自注意力機制需要縮放點積結果的關鍵原…

5.9-selcct_poll_epoll 和 reactor 的模擬實現

5.9-select_poll_epoll 本文演示 select 等 io 多路復用函數的應用方法&#xff0c;函數具體介紹可以參考我過去寫的博客。 先綁定監聽的文件描述符 int sockfd socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(struc…