如何让Python ConfigParser对section名称大小写不敏感?
让ConfigParser对Section名称大小写不敏感的问题解决
问题场景
想要配置ConfigParser,使其调用parser.items(section)、parser.get(section, option)等方法时,对输入的section名称大小写不敏感。例如配置文件dummyConfig.cfg内容如下:
[DEFAULT] a = 1 b = 2 c = 3 [section1] b = 5 d = 4 [ Section 2 ] b = 3 d = 4 e = 5
期望调用parser.items("section1")和parser.items("SECTION1")返回相同结果。尝试修改ConfigParser.SECTCRE正则并添加re.IGNORECASE标志,但调用config_dummy.items('SECTION1')时仍报错NoSectionError: No section: 'SECTION1',相关代码:
from configparser import ConfigParser import re config_dummy = ConfigParser() config_dummy.SECTCRE = re.compile(r"\[(?P<header>[^]]+?)\]", flags=re.IGNORECASE) config_dummy.read('dummyConfig.cfg') config_dummy.items('SECTION1')
问题原因
SECTCRE的re.IGNORECASE仅作用于解析配置文件时的section标题匹配,比如让解析器能识别配置里带空格的标题,但ConfigParser内部存储section名称时,会保留配置文件中的原始大小写(比如配置里的section1就存为section1)。调用方法时,程序会严格匹配内部存储的section键名,因此输入大写的SECTION1找不到对应的存储项,导致报错。
解决方案
方法一:自定义ConfigParser子类(推荐)
重写内部的section查找逻辑,实现大小写不敏感匹配:
from configparser import ConfigParser import re class CaseInsensitiveConfigParser(ConfigParser): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 配置SECTCRE以正确解析带空格的section标题 self.SECTCRE = re.compile(r"\[(?P<header>[^]]+?)\]") def _get_section(self, section, raw=False, vars=None): # 统一将输入的section名称转小写并去除首尾空格 target_section = section.strip().lower() # 遍历所有已加载的section(包含DEFAULT) for sec in self.sections() + ['DEFAULT']: if sec.strip().lower() == target_section: # 找到匹配的原始section名称,调用父类方法处理 return super()._get_section(sec, raw, vars) # 未找到则抛出异常 raise self.NoSectionError(section) # 使用示例 config = CaseInsensitiveConfigParser() config.read('dummyConfig.cfg') print(config.items('SECTION1')) # 返回section1的内容 print(config.items('section 2')) # 返回Section 2的内容 print(config.items('SECTION 2')) # 大写也能匹配
方法二:解析后统一转换section名称
直接修改ConfigParser内部存储的section键名,统一为小写(或大写):
from configparser import ConfigParser import re config = ConfigParser() config.SECTCRE = re.compile(r"\[(?P<header>[^]]+?)\]") config.read('dummyConfig.cfg') # 遍历并替换内部的section键名为小写 new_sections = {} for sec in list(config._sections.keys()): normalized_sec = sec.strip().lower() new_sections[normalized_sec] = config._sections.pop(sec) config._sections = new_sections # 此时需用小写名称调用,或输入后自行转小写 print(config.items('section1')) print(config.items('section 2'))
说明
方法一通过子类重写核心方法,逻辑更稳妥且符合面向对象设计;方法二直接操作内部属性,虽然简单但依赖ConfigParser的内部实现,后续版本可能存在兼容性风险。
内容的提问来源于stack exchange,提问作者Aristide
相关产品推荐
相关产品推荐

