如何引发异常而不是在 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
.
我在使用 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
.