Python ConfigParser 从外部节中插值
使用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}