我正在使用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'}
之类的东西来初始化配置对象,因为某些文件的绝对路径因安装而异。然后我需要传递该配置对象并让各种其他类遍历文件。我不希望每个读取配置的类都必须知道它是使用某些默认值初始化的,并且它应该忽略它们,因为它们不是实际文件。这可能吗?有什么方法可以隐藏.item()和.get()的默认值但仍有插值?谢谢!
答案 0 :(得分:6)
一般来说,我发现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()
的{{3}}。如果configparser基类RawConfigParser
提供一个包含异常转换的选项_options(self, section)
的内部getter,以及一个可以使用它的options()
,那就更好了。然后,在子类化中,我们可以重用_options()
。
对于Python 2,我认为唯一的变化是super()
对super(ConfigParser,self)
的调用。
然后您可以使用:
print config.options('myfiles', no_defaults=True)
并使用该列表进行迭代。
答案 1 :(得分:2)
你不能过滤掉默认值吗?
e.g:
filtered_items = [x for x in config.items('myfiles') if x[0] not in config.defaults()]
答案 2 :(得分:1)
试试这个:
config = ConfigParser.ConfigParser({'blahblahblah': 'blah'})
config.read('test.conf')
blahblahblah
键也会出现在items
中,不是因为它是.ini文件中的模板,而是因为您将其指定为默认值。这就是ConfigParser处理默认值的方式:如果它无法在文件中找到它们,则会分配默认值。
所以在我看来,你在这里有一个简单的概念混淆。
答案 3 :(得分:1)
以下应该只给您 myfiles 部分中的键/值对,而不列出 DEFAULT 中的键/值对:
list(set(config.items('myfiles'))-set(config.items('DEFAULT')))
答案 4 :(得分:0)
ConfigParser
具有default_section
参数。要更改默认行为,只需为其分配None
或''
:
config = ConfigParser(default_section=None)