Python ConfigParser 从外部节中插值

17 投票
4 回答
10122 浏览
提问于 2025-04-17 03:24

使用Python的ConfigParser,能不能在不同的部分之间进行变量替换?我记得好像在哪里见过可以这样做,但我搜索的时候找不到相关的信息。

这个例子虽然不管用,但只是为了让你明白我想做的事情。

[section1]
root = /usr

[section2]
root = /usr/local

[section3]
dir1 = $(section1:root)/bin
dir2 = $(section2:root)/bin

请注意,我使用的是Python 2.4版本。

4 个回答

0

如果你还在用python 2.7,并且需要进行交叉截面的插值,手动使用正则表达式来完成这个任务其实很简单。

下面是代码:

INTERPOLATION_RE = re.compile(r"\$\{(?:(?P<section>[^:]+):)?(?P<key>[^}]+)\}")

def load_something_from_cp(cp, section="section"):
    result = []
    def interpolate_func(match):
        d = match.groupdict()
        section = d.get('section', section)
        key = d.get('key')
        return cp.get(section, key)
    for k, v in cp.items(section):
        v = re.sub(INTERPOLATION_RE, interpolate_func, v)
        result.append(
            (v, k)
        )
    return result

注意事项:

  • 插值过程中没有递归的操作
  • 当处理多个截面时,你需要想办法猜测当前的截面。
2

你可以使用一个特别的部分叫做[DEFAULT]。在这个部分定义的值,可以在其他部分通过插值的方式来访问,即使是旧版本的Python也可以这样做。

14

在 Python 3.2 及以上版本,这段代码是完全有效的:

[Common]
home_dir: /Users
library_dir: /Library
system_dir: /System
macports_dir: /opt/local

[Frameworks]
Python: 3.2
path: ${Common:system_dir}/Library/Frameworks/

[Arthur]
nickname: Two Sheds
last_name: Jackson
my_dir: ${Common:home_dir}/twosheds
my_pictures: ${my_dir}/Pictures
python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}

编辑:

我刚看到你在用 Python 2.4,所以,在 Python 2.4 中无法进行部分插值。这项功能是在 Python 3.2 中引入的 - 查看第 13.2.5 节 - ConfigParser 值的插值

configparser.ExtendedInterpolation

这是一个用于插值的替代处理器,它实现了一种更高级的语法,比如在 zc.buildout 中使用的就是这种方式。扩展插值使用 ${section:option} 来表示来自其他部分的值。插值可以跨越多个层级。为了方便,如果省略了 section: 部分,插值默认使用当前部分(并可能使用特殊部分的默认值)。例如,上面用基本插值指定的配置,使用扩展插值后会变成这样:

   [Paths]
   home_dir: /Users
   my_dir: ${home_dir}/lumberjack
   my_pictures: ${my_dir}/Pictures

也可以从其他部分获取值:

   [Common]
   home_dir: /Users
   library_dir: /Library
   system_dir: /System
   macports_dir: /opt/local

   [Frameworks]
   Python: 3.2
   path: ${Common:system_dir}/Library/Frameworks/

   [Arthur]
   nickname: Two Sheds
   last_name: Jackson
   my_dir: ${Common:home_dir}/twosheds
   my_pictures: ${my_dir}/Pictures
   python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python}

撰写回答