更新 INI 文件而不删除注释
Posted
技术标签:
【中文标题】更新 INI 文件而不删除注释【英文标题】:Update INI file without removing comments 【发布时间】:2014-02-23 22:33:53 【问题描述】:考虑以下 INI 文件:
[TestSettings]
# First comment goes here
environment = test
[Browser]
# Second comment goes here
browser = chrome
chromedriver = default
...
我正在使用 Python 2.7 来更新 ini 文件:
config = ConfigParser.ConfigParser()
config.read(path_to_ini)
config.set('TestSettings','environment',r'some_other_value')
with open(path_to_ini, 'wb') as configfile:
config.write(configfile)
如何在不删除 cmets 的情况下更新 INI 文件。 INI 文件已更新,但 cmets 已删除。
[TestSettings]
environment = some_other_value
[Browser]
browser = chrome
chromedriver = default
【问题讨论】:
你不能用ConfigParser
来做。您需要使用其他库。
你试过allow_no_value参数吗? ***.com/questions/6620637/…
allow_no_value 对读取配置没有影响。也就是说,首先不会读取 cmets 来写下来......
你知道怎么做吗?也许你可以添加你的解决方案?
不得不从 INI 文件切换到 XML。
【参考方案1】:
ConfigObj 在读写 INI 文件时保留comments,并且似乎可以做你想做的事。您描述的场景的示例用法:
from configobj import ConfigObj
config = ConfigObj(path_to_ini)
config['TestSettings']['environment'] = 'some_other_value'
config.write()
【讨论】:
ConfigObj
已过时。见分叉github.com/DiffSK/configobj【参考方案2】:
ConfigObj 是几乎所有情况下的最佳选择。
尽管如此,它不支持没有三引号的多行值,就像 ConfigParser 一样。在这种情况下,一个可行的选项可以是iniparse。
例如:
[TestSettings]
# First comment goes here
multiline_option = [
first line,
second line,
]
您可以通过这种方式更新多行值。
import iniparse
import sys
c = iniparse.ConfigParser()
c.read('config.ini')
value = """[
still the first line,
still the second line,
]
"""
c.set('TestSettings', 'multiline_option', value=value)
c.write(sys.stdout)
【讨论】:
【参考方案3】:配置文件中的cmets在回写时被擦除的原因是write方法根本没有照顾到cmets。它只写键/值对。
绕过此问题的最简单方法是使用自定义注释前缀和 allow_no_value = True 初始化 configparser 对象。 如果我们想保留默认的“#”和“;”文件中的注释行,我们可以使用comment_prefixes='/'。
即,要保留 cmets,您必须欺骗 configparser 使其相信这 不是 注释,这一行是没有值的键。有趣:)
# set comment_prefixes to a string which you will not use in the config file
config = configparser.ConfigParser(comment_prefixes='/', allow_no_value=True)
config.read_file(open('example.ini'))
...
config.write(open('example.ini', 'w'))
【讨论】:
不幸的是,这对我不起作用:cp = ConfigParser.ConfigParser(allow_no_value=True, comment_prefixes='/') TypeError: __init__() got an unexpected keyword argument 'comment_prefixes'
也许这仅适用于较新版本的 Configparser
好的,我刚刚用 python3 试了一下,就可以了。使用 python2 将打印上面的错误消息
这对注释行没有帮助,它们仍然被删除
这最终使我所有的 cmets 小写
@eric.frederich 这是因为configparser
有一个默认转换器。你可以通过config.optionxform = lambda option: option
绕过它。见this link【参考方案4】:
ConfigUpdater
可以更新 .ini
文件并保留 cmets:pyscaffold/configupdater。
我不知道它是否适用于 Python 2。
来自docs:
与 ConfigParser 的主要区别是:
更新配置文件中的微创更改, 正确处理 cmets,
【讨论】:
以上是关于更新 INI 文件而不删除注释的主要内容,如果未能解决你的问题,请参考以下文章