我正在使用 configparser 来读取备份系统的配置。 选项之一(输出路径)通常包含节名本身。
[DEFAULT]
compression=gzip
[foo]
output=/Backups/foo/
[pizza]
output=/BigDisk/Backups/
[bar]
output=/Backups/bar/
现在我想摆脱手动附加节名称的情况,而是想使用字符串插值。类似于以下内容:
[DEFAULT]
compression=gzip
output=/Backups/%(SECTION)s/
[foo]
[pizza]
output=/BigDisk/Backups/
[bar]
不幸的是,我还没有找到可以扩展为节名称的变量名称(显然不是 SECTION
)。
这是否可能(理想情况下无需构建我自己的 ConfigParser 子类)?
一个丑陋的解决方法是添加一个选项append_section_name
(并将其设置为DEFAULT
部分中的yes
和no
在 pizza
部分)并手动进行插值。我宁愿不...
最佳答案
我需要做同样的事情,我发现在 Python 3.x 中很容易做到(在 Python 3.4 上测试):
- 创建
ExtendedInterpolation
类 (MyExtendedInterpolation
) 的子类并重写before_get()
方法。首先,创建一个新值来进行自定义替换。我发现使用字符串Template
类和调用safe_substitute()
方法最简单。接下来,返回对父类(super class)before_get()
方法的调用结果。 - 使用自定义插值类创建
ConfigParser
对象。 - 照常使用
ConfigParser
对象。
希望有帮助。
下面的工作代码:
#!/usr/bin/env python3
from configparser import ConfigParser, ExtendedInterpolation
from string import Template
class MyExtendedInterpolation(ExtendedInterpolation):
def before_get(self, parser, section, option, value, defaults):
value = Template(value).safe_substitute({'SECTION': section})
return super().before_get(parser, section, option, value, defaults)
if __name__ == '__main__':
cp = ConfigParser(interpolation=MyExtendedInterpolation())
cp.read_string("""
[DEFAULT]
compression=gzip
output=/Backups/${SECTION}/
[foo]
[pizza]
output=/BigDisk/Backups/
[bar]
""")
for section in cp.sections():
print('[{!s}]'.format(section))
for option in cp[section]:
print(' {!s} = {!s}'.format(option, cp.get(section, option)))
下面的脚本输出。请注意 output
选项值如何包含 [foo]
和 [bar]
部分的部分名称。
[foo]
compression = gzip
output = /Backups/foo/
[pizza]
output = /BigDisk/Backups/
compression = gzip
[bar]
compression = gzip
output = /Backups/bar/
相关引用资料:
关于python-3.x - 如何使用 configparser 插入节名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36620168/