简体   繁体   English

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

[英]How to raise exception instead of returning None in Python “ConfigParser” section?

I have a problem using the configparser module.我在使用configparser模块时遇到问题。

import configparser

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

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

I would like my code to raise an exception if the parsed configuration is missing a required field.如果解析的配置缺少必填字段,我希望我的代码引发异常。 However, getboolean() returns None in this case instead of raising a KeyError as expected.但是,在这种情况下, getboolean()返回None而不是如预期的那样引发KeyError

I could possibly use foo["missing_field"] which does raise an exception.我可能会使用foo["missing_field"]会引发异常。 However, in such case, I loose the boolean conversion.但是,在这种情况下,我放弃了 boolean 转换。

I could explicitly test for if res is None: and throw the exception manually but I have a lot of config fields so that would be cumbersome.我可以显式测试if res is None:并手动抛出异常,但我有很多配置字段,所以这很麻烦。

Does Python provide an elegant way to force strict config parsing? Python 是否提供了一种优雅的方式来强制进行严格的配置解析?

You can use getboolean on the config object directly:您可以直接在配置 object 上使用getboolean

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

which will raise a NoOptionError if missing_field doesn't exist:如果missing_field不存在,这将引发NoOptionError

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

The different behavior for getboolean on the proxy is because it calls the relevant getter with a default fallback=None .代理上getboolean的不同行为是因为它使用默认的fallback=None调用相关的 getter。 The problem is that the "regular" get uses a special _UNSET object as the default fallback and then does:问题是“常规” get使用特殊的_UNSET object 作为默认后备,然后执行:

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

So, as an alternative (which came up in the discussion for @Tomerikoo's answer and @chepner suggested in a comment to this answer), you can pass in _UNSET as the fallback value when using the section proxy.因此,作为替代方案(在@Tomerikoo 的答案的讨论中出现,@chepner 在对此答案的评论中建议),您可以在使用部分代理时传入_UNSET作为后备值。 As per your original code:根据您的原始代码:

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

Well... @Kemp found a tweaky behaviour that solves this easily, but as I already went through the following trouble, I might as well just post it...好吧...@Kemp 找到了一个可以轻松解决此问题的微调行为,但是由于我已经遇到了以下麻烦,所以我不妨将其发布...


The default behavior doesn't raise an exception, but why not "fix" it according to your needs?默认行为不会引发异常,但为什么不根据您的需要“修复”它呢? You can create a sub-class of ConfigParser that only wraps getboolean with a check if the option actually exists and then returns the original getboolean value.您可以创建一个ConfigParser的子类,它只包装getboolean并检查option是否实际存在,然后返回原始的getboolean值。 I think the nice thing about this option is that you don't need to change your code at all - just change the initial config =... line to use the new class:我认为这个选项的好处是您根本不需要更改代码 - 只需更改初始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)

Now doing:现在做:

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

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

Will give (truncated):将给出(截断):

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

As opposed to:相对于:

True
None

With the regular configparser.ConfigParser .使用常规configparser.ConfigParser

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM