如何从Python ConfigParser.items()中排除默认值?

2024-04-27 06:02:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用ConfigParser从配置文件加载数据,如下所示:

测试配置:

[myfiles]
fileone: %(datadir)s/somefile.foo
filetwo: %(datadir)s/nudderfile.foo

加载.py:

import ConfigParser

config = ConfigParser.ConfigParser({'datadir': '/tmp'})
config.read('test.conf')

print config.items('myfiles')
print config.get('myfiles', 'datadir')

输出:

$ python load.py 
[('datadir', '/tmp'), ('filetwo', '/tmp/nudderfile.foo'), ('fileone', '/tmp/somefile.foo')]
/tmp

我很惊讶变量替换的默认值('datadir', '/tmp')作为.items().get()返回的一部分出现,就好像它们是配置文件中的值一样。这种行为是预期的吗?任何解决方法,这样我就可以简单地迭代.items(),而不必在那里获取默认字典值,但仍然使用魔术插值?

引用:http://docs.python.org/library/configparser.html

谢谢!

更新:有人指出,这是预期的行为:默认值与配置文件中的任何其他名称/值对一样。类似地,配置文件中的名称/值对也可用于“magic interpolation”,因此如果我定义:

foo: bar
zap: %(foo)snowl

我会得到[... ('zap': 'barnowl')]

这很不错,但我仍然想知道我是否能完成我想要完成的任务:在配置文件中迭代名称/值对,使用变量插值,而不使用默认值。

我的特定场景是这样的:我想用{basedir: '/foo/bar'}之类的东西初始化配置对象,因为到某些文件的绝对路径因安装而异。然后我需要将这个配置对象传递给其他类,并让其他类遍历这些文件。我不希望读取配置的每个类都知道它是用某些默认值初始化的,并且应该忽略它们,因为它们不是实际的文件。这可能吗?有什么方法可以隐藏.item()和.get()的默认值,但仍有插值?谢谢!


Tags: 文件名称configgetfoo配置文件itemstmp
3条回答

一般来说,我发现configparser.Configparser类非常有用,但也缺少。Others have, too

然而,它可以被子类化和扩展,有时很好,有时不太好(=非常依赖于实现)

这里有一个解决您问题的方法,在Python3中进行了测试:

class ConfigParser(configparser.ConfigParser):
    """Can get options() without defaults
    """
    def options(self, section, no_defaults=False, **kwargs):
        if no_defaults:
            try:
                return list(self._sections[section].keys())
            except KeyError:
                raise NoSectionError(section)
        else:
            return super().options(section, **kwargs)

这是一个糟糕的例子,因为它正在部分复制options()the source code。如果configparser基类RawConfigParser提供一个包含异常转换的选项_options(self, section)的内部getter,以及一个使用该选项的options(),则会更好。然后,在子类化中,我们可以重用_options()

对于Python 2,我相信唯一的改变是对super()的调用。

然后您可以使用:

print config.options('myfiles', no_defaults=True)

并使用该列表进行迭代。

试试这个:

config = ConfigParser.ConfigParser({'blahblahblah': 'blah'})
config.read('test.conf')

blahblahblah键也将出现在items中,不是因为它是.ini文件中的模板,而是因为您将其指定为默认值。这就是ConfigParser处理默认值的方式:如果在文件中找不到它们,它将分配它们的默认值。

所以在我看来,你对这里的概念有一个简单的混淆。

你就不能过滤掉默认值吗?

例如:

filtered_items = [x for x in config.items('myfiles') if x[0] not in config.defaults()]

相关问题 更多 >