如何引发异常而不是在 Python "ConfigParser" 部分返回 None?

How to raise exception instead of returning None in Python "ConfigParser" section?

我在使用 configparser 模块时遇到问题。

import configparser

config = configparser.ConfigParser()
config.read_dict({"foo": {}})

foo = config["foo"]
foo.getboolean("missing_field")

如果解析的配置缺少必填字段,我希望我的代码引发异常。但是,在这种情况下 getboolean() returns None 而不是按预期提高 KeyError

我可能会使用 foo["missing_field"],它会引发异常。但是,在这种情况下,我松开了布尔转换。

我可以显式测试 if res is None: 并手动抛出异常,但我有很多配置字段,所以这会很麻烦。

Python 是否提供了一种优雅的方式来强制执行严格的配置解析?

您可以直接在配置对象上使用getboolean

config.getboolean("foo", "missing_field")

如果 missing_field 不存在,将引发 NoOptionError

configparser.NoOptionError: No option 'missing_field' in section: 'foo'

代理上 getboolean 的不同行为是因为它使用默认 fallback=None 调用相关 getter。问题是“常规”get 使用特殊的 _UNSET 对象作为默认后备,然后执行:

if fallback is _UNSET:
    raise NoOptionError(option, section)
else:
    return fallback

因此,作为替代方案(在@Tomerikoo 的回答的讨论中提出,@chepner 在对该回答的评论中提出建议),您可以在使用该部分时传入 _UNSET 作为回退值代理。根据您的原始代码:

foo.getboolean("missing_field", fallback=configparser._UNSET)

好吧...@Kemp 发现了一个可以轻松解决此问题的微调行为,但由于我已经遇到了以下问题,我还不如 post 它...


默认行为不会引发异常,但为什么不根据您的需要“修复”它呢?您可以创建 ConfigParser 的子 class,它只包装 getboolean,检查 option 是否实际存在,然后 returns 原始 getboolean 价值。我认为此选项的好处是您根本不需要更改代码 - 只需更改初始 config = ... 行即可使用新的 class:

import configparser

class MyConfig(configparser.ConfigParser):
    def getboolean(self, section, option, *, raw=False, vars=None,
                   fallback=configparser_UNSET, **kwargs):
        if self.get(section, option, raw=raw, vars=vars, fallback=fallback) == fallback:
            raise configparser.NoOptionError(option, section)

        return super().getboolean(section, option, raw=raw, vars=vars, fallback=fallback)

正在做:

config = MyConfig()
config.read_dict({"foo": {'existing_field': '1'}})

foo = config["foo"]
print(foo.getboolean("existing_field"))
print(foo.getboolean("missing_field"))

将给出(截断):

True
Traceback (most recent call last):
...
configparser.NoOptionError: No option 'missing_field' in section: 'foo'

相对于:

True
None

与常规 configparser.ConfigParser.