在ConfigParser中如何仅获取节局部选项?

问题描述 投票:0回答:1

考虑以下名为foo.py的MWE:

#!/usr/bin/env python3
from configparser import ConfigParser

if __name__ == "__main__":
    cfg = ConfigParser()
    with open("foo.ini") as ini:
        cfg.read_file(ini)
    for section in cfg.sections():
        print("[%s]" % (section))
        for option, value in cfg.items(section):
            print("%s = %s" % (option, value))

...及其随附的foo.ini

[DEFAULT]
basedir = /foo/bar
sourcedir = %(basedir)s/baz

[task:1]
sourcedir = /usr
workdir = %(sourcedir)s/src

[task:2]
hdrdir = %(sourcedir)s/include

脚本在运行时将产生以下内容:

[task:1]
basedir = /foo/bar
sourcedir = /usr
workdir = /usr/src
[task:2]
basedir = /foo/bar
sourcedir = /foo/bar/baz
hdrdir = /foo/bar/baz/include

期望的结果是(通过ConfigParser.items()专门迭代(内插的))选项局部于给定部分

raw=True传递到ConfigParser.items()不会影响项目列表,除了要插值[[not(总之不是期望的结果)。”

现在,我可以在初始脚本的此修改版本中执行类似的操作:

#!/usr/bin/env python3 from configparser import ConfigParser if __name__ == "__main__": cfg = ConfigParser() with open("foo.ini") as ini: cfg.read_file(ini) print("; sections: %s" % (cfg.sections())) print("; defaults: %s" % (cfg.defaults())) for section in cfg.sections(): print("[%s]" % (section)) print("; options = %s" % (cfg.options(section))) for option, value in cfg.items(section): if option in cfg.defaults(): # can't use cfg.defaults()[option] ... that's the raw value if cfg[cfg.default_section][option] == value: continue print("%s = %s" % (option, value))

...产生:

; sections: ['task:1', 'task:2'] ; defaults: OrderedDict([('basedir', '/foo/bar'), ('sourcedir', '%(basedir)s/baz')]) [task:1] ; options = ['sourcedir', 'workdir', 'basedir'] sourcedir = /usr workdir = /usr/src [task:2] ; options = ['hdrdir', 'basedir', 'sourcedir'] hdrdir = /foo/bar/baz/include

因此乍一看就可以使用,但是会过滤掉局部值与全局相同名称的选项相同的选项。

现在,这似乎仅是一个外观问题,但就我而言,选项是否在节内本地存在还是其值是从默认节继承而来的,仍然存在语义上的区别(请考虑多个文件,多个继承项)。选项...)。要指出的是,这是一种天真的方法,对我不起作用。

[因此问题:如何获得just

实际上在.ini文件的一部分内的选项,而没有所有这些全局继承的选项?有没有一种方法可以做到这一点而无需进入configparser模块的胆量并篡改非公共方法和东西?
python-3.x configparser
1个回答
0
投票
检查code of ConfigParser,我看不到要使用的公共API。实际上,ConfigParser中的任何方法都使用默认值扩展了给定的部分。

因此,IMO唯一直接的方法是在配置或ConfigParserConfigParser constructor参数)中更改默认部分。

ConfigParser

但是副作用是,对于此实例化的default_section,此“插值”将不再起作用。但是,您仍然可以自行设置默认/后备机制:

if __name__ == "__main__": cfg = ConfigParser(default_section="whatever") # (...)

我在“插值”两边加上引号,因为ConfigParser中的cfg = ConfigParser(default_section="whatever") cfg.get(mysection, myoption, fallback=cfg.get('DEFAULT', myoption)) 。但是,它与我们在此处讨论的插值无关。

© www.soinside.com 2019 - 2024. All rights reserved.