使用ConfigParser修改配置文件为何自动转小写键名并替换冒号为等号?
解决ConfigParser修改ini文件时键名小写、分隔符变更的问题
我来帮你分析一下问题所在,以及对应的解决办法:
问题原因
Python的ConfigParser(Python3中为configparser.ConfigParser)有几个默认行为,直接导致了你的配置文件被意外修改:
- 键名自动转小写:默认情况下,
ConfigParser会通过optionxform方法把所有配置项的键名转为小写,所以写入文件时原本的大写键名全变成了小写。 - 统一键值分隔符:虽然
ConfigParser读取时能识别:和=两种分隔符,但写入时会默认用=作为统一分隔符,因此原文件里的:会被替换成=。 - 你提到的部分键名异常(比如
FILE变成configfile、LOGFILE变成LOGNAME),大概率是测试时的输入失误,并非ConfigParser的默认行为。
解决方案
1. 保留键名的大小写
初始化ConfigParser后,修改它的optionxform属性,让它直接返回原字符串,就能禁用自动转小写的逻辑:
from configparser import ConfigParser parser = ConfigParser() # 关键:禁用键名小写转换 parser.optionxform = str parser.read('nice.ini')
2. 保留冒号作为键值分隔符(可选)
如果需要严格保留原文件中的:分隔符,ConfigParser的默认write方法做不到——因为它不会记录每个键值对原本使用的分隔符。这里有两个可行选择:
使用
configobj第三方库:这个库可以完美保留原ini文件的格式(包括分隔符、大小写、注释等),安装和使用都很简单:from configobj import ConfigObj def update_Val(): while (True): a = input("Do you want to update the pass of env?yes/no: ") if a.lower() == "yes": sect = input("Enter env name to update pass or q to exit : ") if sect == 'q': exit(120) passwd = input("Enter pass to overwrite or q to exit : ") if passwd == 'q': exit(120) # 读取配置并保留原格式 config = ConfigObj('nice.ini', encoding='utf-8') config[sect]['password'] = passwd # 写入时严格保留原格式 config.write() elif a.lower() == "no": print("file updated") break update_Val()安装命令:
pip install configobj自定义
ConfigParser写入逻辑:如果不想依赖第三方库,可以子类化ConfigParser并重写write方法,手动控制分隔符的使用,但这种方式比较繁琐,适合对格式有极端要求的场景。
3. 修复你的原代码
把保留大小写的逻辑加入原代码,同时移除多余的文件关闭操作(with上下文管理器会自动关闭文件),修改后的完整代码如下:
from configparser import ConfigParser parser = ConfigParser() # 禁用键名小写转换 parser.optionxform = str parser.read('nice.ini') def update_Val(): while (True): a = input("Do you want to update the pass of env?yes/no: ") if a.lower() == "yes": sect = input("Enter env name to update pass or q to exit : ") if sect == 'q': exit(120) passwd = input("Enter pass to overwrite or q to exit : ") if passwd == 'q': exit(120) parser.set(sect, 'password', passwd) with open('nice.ini', 'w') as configfile: parser.write(configfile) elif a.lower() == "no": print("file updated") break update_Val()
这样修改后,键名的大小写会被完全保留,只是分隔符仍会统一为=;如果必须保留原文件的:分隔符,建议优先使用configobj库。
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

