python原生處理properties文件

這個工具類使用 Python 的 configparser 模塊操作 .properties 文件,核心是將 .properties 格式適配為 configparser 支持的 .ini 格式。

核心代碼解釋

1. 類初始化與配置解析
class Properties:def __init__(self, file_path: str, encoding: str = 'utf-8'):self.file_path = file_pathself.encoding = encodingself.config = configparser.ConfigParser(allow_no_value=True,           # 允許無值的鍵delimiters=('=',),             # 使用等號作為分隔符comment_prefixes=('#', '!'),   # 支持 # 和 ! 開頭的注釋inline_comment_prefixes=('#', '!')  # 支持行內注釋)self.config.optionxform = str  # 保留鍵的大小寫self._section = 'DEFAULT'      # 默認使用 DEFAULT 部分self.read()  # 讀取文件內容
  • configparser.ConfigParser 是核心解析器
  • optionxform = str 防止鍵名被轉為小寫
  • 添加 [DEFAULT] 部分適配 .properties 格式
2. 讀取文件
def read(self) -> None:try:with open(self.file_path, 'r', encoding=self.encoding) as f:# 添加 [DEFAULT] 部分使 configparser 能解析config_content = f"[{self._section}]\n" + f.read()self.config.read_string(config_content)except FileNotFoundError:# 文件不存在時創建空配置self.config[self._section] = {}
  • 讀取文件內容并在前面添加 [DEFAULT] 部分
  • read_string 方法從字符串解析配置
3. 保存文件
def save(self) -> None:with open(self.file_path, 'w', encoding=self.encoding) as f:# 寫入時跳過 [DEFAULT] 部分,保持 .properties 格式for key, value in self.config.items(self._section):if value is None:f.write(f"{key}\n")else:f.write(f"{key}={value}\n")
  • 保存時去掉 [DEFAULT] 部分,恢復 .properties 格式
  • 處理無值的鍵(如 key= 或單獨的 key

新增功能實現

1. 遍歷所有鍵值對
def items(self) -> List[Tuple[str, str]]:"""獲取所有鍵值對的列表"""return list(self.config.items(self._section))def keys(self) -> List[str]:"""獲取所有鍵的列表"""return list(self.config.options(self._section))def values(self) -> List[str]:"""獲取所有值的列表"""return [value for _, value in self.config.items(self._section)]
2. 清空文件內容
def clear(self) -> None:"""清空 properties 文件的所有內容"""self.config[self._section] = {}self.save()

完整代碼

以下是添加了遍歷和清空功能的完整代碼:

import configparser
from typing import Dict, Optional, Union, List, Tupleclass Properties:"""處理 .properties 文件的工具類,使用 configparser 實現"""def __init__(self, file_path: str, encoding: str = 'utf-8'):"""初始化 Properties 工具類Args:file_path: properties 文件路徑encoding: 文件編碼,默認為 utf-8"""self.file_path = file_pathself.encoding = encodingself.config = configparser.ConfigParser(allow_no_value=True,delimiters=('=',),comment_prefixes=('#', '!'),inline_comment_prefixes=('#', '!'))self.config.optionxform = str  # 保留鍵的大小寫self._section = 'DEFAULT'  # 默認使用 DEFAULT 部分self.read()def read(self) -> None:"""讀取 properties 文件內容"""try:with open(self.file_path, 'r', encoding=self.encoding) as f:# 添加默認 section 以兼容 .properties 格式config_content = f"[{self._section}]\n" + f.read()self.config.read_string(config_content)except FileNotFoundError:# 文件不存在,創建空配置self.config[self._section] = {}def get(self, key: str, default: Optional[str] = None) -> Optional[str]:"""獲取指定鍵的值Args:key: 鍵名default: 鍵不存在時的默認值Returns:鍵對應的值,或默認值"""return self.config.get(self._section, key, fallback=default)def set(self, key: str, value: str) -> None:"""設置或修改鍵值對Args:key: 鍵名value: 值"""self.config.set(self._section, key, value)def remove(self, key: str) -> None:"""刪除指定鍵Args:key: 鍵名"""self.config.remove_option(self._section, key)def set_batch(self, items: Union[Dict[str, str], List[Tuple[str, str]]]) -> None:"""批量設置鍵值對Args:items: 字典或元組列表形式的鍵值對"""if isinstance(items, dict):for key, value in items.items():self.set(key, value)elif isinstance(items, list):for key, value in items:self.set(key, value)def save(self) -> None:"""保存當前配置到文件"""with open(self.file_path, 'w', encoding=self.encoding) as f:# 寫入時跳過 section 頭,保持 .properties 格式for key, value in self.config.items(self._section):if value is None:f.write(f"{key}\n")else:f.write(f"{key}={value}\n")def items(self) -> List[Tuple[str, str]]:"""獲取所有鍵值對的列表"""return list(self.config.items(self._section))def keys(self) -> List[str]:"""獲取所有鍵的列表"""return list(self.config.options(self._section))def values(self) -> List[str]:"""獲取所有值的列表"""return [value for _, value in self.config.items(self._section)]def clear(self) -> None:"""清空 properties 文件的所有內容"""self.config[self._section] = {}self.save()def __getitem__(self, key: str) -> str:"""通過 [] 語法獲取值"""return self.get(key)def __setitem__(self, key: str, value: str) -> None:"""通過 [] 語法設置值"""self.set(key, value)def __contains__(self, key: str) -> bool:"""檢查鍵是否存在"""return self.config.has_option(self._section, key)def __str__(self) -> str:"""返回所有鍵值對的字符串表示"""return '\n'.join([f"{k}={v}" for k, v in self.config.items(self._section)])

使用示例

以下是如何使用新增功能的示例:

# 初始化并讀取文件
props = Properties('config.properties')# 遍歷所有鍵值對
for key, value in props.items():print(f"{key} = {value}")# 獲取所有鍵
all_keys = props.keys()
print("所有鍵:", all_keys)# 獲取所有值
all_values = props.values()
print("所有值:", all_values)# 清空文件
props.clear()
print("文件已清空")# 添加新鍵值對
props['new_key'] = 'new_value'
props.save()

工作原理總結

這個工具類通過以下方式實現 .properties 文件操作:

  1. 格式適配

    • 讀取時在文件內容前添加 [DEFAULT] 部分,使其符合 .ini 格式
    • 保存時去掉 [DEFAULT] 部分,恢復 .properties 格式
  2. 核心操作

    • configparser 負責解析和生成配置
    • optionxform = str 保持鍵的原始大小寫
    • allow_no_value=True 支持無值的鍵
  3. 新增功能

    • items()/keys()/values() 方法提供遍歷功能
    • clear() 方法清空所有配置并保存

這樣就可以方便地操作 .properties 文件,無需了解底層實現細節。

DEFAULT 部分是 Python configparser 模塊的一個特殊概念,源于 .ini 配置文件格式的設計。讓我詳細解釋它的作用、必要性以及歷史淵源:

1. DEFAULT 部分的作用

.ini 格式中,[DEFAULT] 是一個特殊的全局 section,它的作用是:

  • 為所有其他 section 提供默認值
  • 定義所有 section 都能繼承的公共配置

例如:

[DEFAULT]
host = localhost
port = 3306[database]
name = mydb
user = root[test]
name = testdb

這里:

  • [database] 實際繼承了 host=localhostport=3306
  • [test] 同樣繼承了 hostport,但覆蓋了 name

2. 為什么在 .properties 文件中需要 DEFAULT?

.properties 文件本身沒有 [section] 的概念,它是扁平的鍵值對結構。但 configparser 模塊必須有一個 section 才能工作,因此我們:

  • 讀取時:人為添加 [DEFAULT] 部分,讓 configparser 能解析
  • 保存時:去掉 [DEFAULT] 部分,保持 .properties 格式

這是一種適配技巧,讓 configparser 能處理 .properties 文件。

3. 歷史淵源

.ini 格式的起源
  • .ini(Initialization)格式最早出現在 Windows 3.1 系統中,用于存儲程序配置
  • 它使用 [section] 分組,支持層級化配置
  • [DEFAULT] 作為特殊 section,提供全局默認值
.properties 格式的起源
  • .properties 是 Java 語言的標準配置格式
  • 它是簡單的 key=value 結構,沒有 section 概念
  • 通常通過 java.util.Properties 類加載
Python 的 configparser
  • Python 的 configparser 模塊最初設計用于解析 .ini 格式
  • 為了兼容 .properties,我們需要通過 [DEFAULT] 做適配

4. 必須使用 DEFAULT 嗎?

是的,在使用 configparser 時必須有一個 section:

  • 如果不指定 [DEFAULT]configparser 會拋出 MissingSectionHeaderError
  • 其他替代方案(如自定義解析器)會更復雜,失去使用標準庫的優勢

可以將 [DEFAULT] 視為 .properties 文件的隱式容器,它只是讓 configparser 正常工作的必要手段。

5. 實際影響

使用 [DEFAULT].properties 文件沒有副作用:

  • 讀取和保存時自動處理 [DEFAULT],文件本身不會改變
  • 所有鍵值對仍按原始格式存儲
  • 工具類的 API(如 get()set())對用戶保持透明,無需關心底層實現

總結

DEFAULT 部分是 configparser 模塊的特性,用于適配 .ini 格式:

  • 在處理 .properties 文件時,它是必要的適配層
  • 不會影響文件內容,只是內存中的解析結構
  • 讓我們能用標準庫處理 .properties,避免手寫解析器的復雜性

理解這一點后,你可以專注于使用工具類的 API,而無需擔心 [DEFAULT] 的底層細節。

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

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

相關文章

【java 安全】 IO流

前言 IO是指 Input/Output,即輸入和輸出。以內存為中心: Input指從外部讀入數據到內存,例如把文件從磁盤讀取到內存,從網絡讀取數據到內存等等。Output指把數據從內存輸出到外部,例如把數據從內存寫入到文件&#xff0…

音視頻同步技術初剖析:原理、實現與FFmpeg分析

音視頻同步的基本原理 音視頻同步主要依靠以下幾個關鍵點:時間戳機制: 在封裝格式(如MP4)中,音頻幀和視頻幀都帶有時間戳(PTS, Presentation Time Stamp)這些時間戳表示該幀應該在什么時間被呈現同步策略: 音頻為主時鐘&#xff1…

掌控網頁的魔法之書:JavaScript DOM的奇幻之旅

掌控網頁的魔法之書:JavaScript DOM的奇幻之旅 在網頁開發的世界里,JavaScript就像一位魔法師,而DOM(文檔對象模型)則是它的魔法之書。沒有DOM,JavaScript就像失去了咒語的巫師,無法操控網頁的元…

【C語言】深入理解柔性數組:特點、使用與優勢分析

C語言學習 柔性數組 友情鏈接:C語言專欄 文章目錄C語言學習前言:柔性數組一、柔性數組的特點二、柔性數組的使用三、柔性數組的優勢總結附錄上文鏈接專欄前言: 在有結構體和動態內存分配的知識后,今天咱們來說說柔性數組吧&…

RV126平臺NFS網絡啟動終極復盤報告

1. 初始目標與環境目標: 將RV1126開發板的啟動方式,由從eMMC內部存儲掛載根文件系統(rootfs),切換為通過網絡掛載位于NFS服務器上的根文件系統。動機: 提升開發調試效率,實現代碼修改后僅需重啟即可驗證,免…

一臺顯示器上如何快速切換兩臺電腦主機?

我注意到很多人會遇到一個常見的情況:他們有兩臺電腦,一臺舊的用來處理基本的辦公任務,另一臺新的用來玩游戲。新手通常會用 DP端口連接第一臺電腦的顯示器,用 HDMI 連接第二臺電腦。當他們想在兩臺電腦之間切換時,經常…

抗輻照與國產替代:ASM1042在衛星光纖放大器(EDFA)中的應用探索

摘要:本文以國科安芯推出的ASM1042芯片為例,通過分析ASM1042的抗輻照性能、高速數據傳輸能力、可靠性以及國產化優勢,結合EDFA系統的需求特點,深入探討了其在商業衛星光纖放大器(EDFA)項目中的應用潛力。AS…

鴻蒙ArkUI:聲明式開發,高效構建全場景體驗

目錄 導言:開啟鴻蒙應用開發的新范式 ArkUI框架概覽 - 鴻蒙UI的靈魂 深入核心 - 聲明式UI開發范式 命令式 vs 聲明式:范式革命 ArkUI如何實現聲明式? 創建內置組件 創建自定義組件 自定義組件的基本結構 ArkUI框架的核心特性與優勢 …

數據查找 二叉查找樹

查找一般分為有序查找和無序查找,這邊在講有序查找例二分查找二分查找就是在有序數組中,通過mid(lowhigh)/2來判定中間值,將中間值與待查找的值進行比較,如果待查找的值大于中間值,那么就將范圍縮小,查找右…

幾款開源的安全監控與防御工具分享

安全監控與防御工具概述 在現代網絡安全架構中,合理選擇和部署一系列的安全監控、檢測、響應工具至關重要。下面我們將介紹一些常見的安全工具,包括 Elkeid、Wazuh、Caldera、ELK、Snort、Suricata、OpenHFW、OSSEC、GScan 和 Sysom,并詳細介紹它們的下載鏈接、用處、使用方…

Elasticsearch:ES|QL 改進的時間線

作者:來自 Elastic Toms Mura 讓我們回顧一下 ES|QL 的歷史和它的改進。 更多閱讀,Elasticsearch:ES|QL 查詢展示。 Elasticsearch 配備了眾多新功能,幫助你為自己的用例構建最佳搜索方案。查看我們的示例筆記本了解更多內容&…

Linux | Bash 子字符串提取

注:本文為 “ Bash 子字符串提取” 相關合輯。 英文引文,機翻未校。 如有內容異常,請看原文。 How to Extract Bash Substring? [5 methods] 如何提取 Bash 子字符串?[5 種方法] 2024-04-28 00:00:00 In Bash, a substring is…

Vue2 前端開發 - vue-quill-editor 富文本編輯器(編輯器基礎案例、編輯器配置參數解讀、編輯器事件)

一、vue-quill-editor 1、vue-quill-editor 概述vue-quill-editor 是一個基于 Quill 富文本編輯器的 Vue 組件vue-quill-editor 在 Vue 2 項目中可以很方便地集成與使用2、vue-quill-editor 安裝 執行如下指令,安裝 vue-quill-editor npm install vue-quill-editor …

斷網情況下,網線直連 Windows 筆記本 和Ubuntu 服務器

在斷網情況下,通過網線直連 Windows 筆記本 和 Ubuntu 服務器,并使用 VSCode 訪問服務器及 Docker 容器 的步驟如下:1. 物理連接(網線直連) 1.1 使用網線連接 用 網線(Cat5e 或更高) 連接 Windo…

消息隊列總結

為什么需要消息隊列? 隨著互聯網快速發展,業務規模不斷擴張,技術架構從單體演進到微服務,服務間調用復雜、流量激增。為了解耦服務、合理利用資源、緩沖流量高峰,「消息隊列」應運而生,常用于異步處理、服務…

C#引用轉換核心原理:類型視角切換

🔍 C#引用轉換核心原理:類型視角切換 引用類型由內存指針和類型標記組成(如圖1)。引用轉換不改變內存地址,僅改變編譯器識別對象的“視角”: B myVar1 new B(); // 實際B類型對象 A myVar2 (A)myV…

重要發布丨MaxKB V2正式發布,助力用戶快速構建企業級智能體

2025年7月18日,MaxKB V2版本正式發布。MaxKB是一個強大易用的企業級智能體平臺,致力于解決企業AI落地所面臨的技術門檻高、部署成本高、迭代周期長等問題,讓企業用戶落地AI更簡單。 秉承“開箱即用,伴隨成長”的設計理念&#xff…

大語言模型任務分解與匯總:從認知瓶頸到系統化解決方案

一、緣起:為什么大模型需要"分而治之" 1.1 從一個真實場景說起 設想這樣一個場景:你要求GPT-4幫你完成一份包含市場調研、競品分析、財務預測和戰略規劃的商業計劃書。即使是最先進的大模型,面對這樣的復雜任務也會"力不從心&…

Spring核心注解@RequestMapping詳解

RequestMapping 是 Spring Framework 中一個核心注解,用于在 Spring MVC(或 Spring WebFlux)中將 HTTP 請求映射到特定的處理器(Controller 中的方法)或處理器類。它告訴 Spring 框架:當一個匹配特定條件的…

OSPF路由協議的協商過程

OSPF的知識點非常多,協議過程也是一個不大不小的知識點,今天就簡單的說一下,OSPF是如何進行協商的。OSPF(Open Shortest Path First)協議是一種用于路由選擇的動態鏈路狀態協議,是大型網絡普遍使用的動態路…