繁体   English   中英

如何从 Python ConfigParser .items() 中排除 DEFAULT?

[英]How to exclude DEFAULTs from Python ConfigParser .items()?

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

测试.conf:

[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

谢谢!

更新:有人指出这是预期的行为:默认值就像配置文件中的任何其他名称/值对一样。 同样,配置文件中的名称/值对也可用于“魔术插值”,因此如果我定义:

foo: bar
zap: %(foo)snowl

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

这非常简洁,但我仍然想知道我是否可以完成我想要完成的任务:在我的配置文件中迭代名称/值对,使用变量插值,没有默认值。

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

一般来说,我发现configparser.Configparser类非常有用,但也很缺乏。 其他人也有

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

这是您的问题的解决方案,已在 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() 的源代码 如果 configparser 基类RawConfigParser提供一个内部 getter 选项_options(self, section) ,它将合并异常转换,以及一个将使用它的options() ,那就更好了。 然后,在子类化中我们可以重用_options()

对于 Python 2,我相信唯一的变化是super()调用super(ConfigParser,self)

然后您可以使用:

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

并且还使用该列表进行迭代。

你不能过滤掉默认值吗?

例如:

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

尝试这个:

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

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

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

下面应该只给你myfiles部分中的键/值对,而不列出DEFAULT 中的那些:

list(set(config.items('myfiles'))-set(config.items('DEFAULT')))

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

test.conf:

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

load.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

谢谢!

更新:已经指出这是预期的行为:默认值与配置文件中的任何其他名称/值对一样。 同样,配置文件中的名称/值对也可用于“魔术插值”,因此如果我定义:

foo: bar
zap: %(foo)snowl

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

那很整洁,但是我仍然想知道我是否可以完成我想完成的工作:遍历配置文件中的名称/值对,使用变量插值,而不使用默认值。

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

暂无
暂无

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

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