【问题标题】:Writing comments to files with ConfigParser使用 ConfigParser 向文件写入注释
【发布时间】:2011-10-01 00:40:57
【问题描述】:

如何将 cmets 写入节内的给定文件?

如果我有:

import ConfigParser
with open('./config.ini', 'w') as f:
    conf = ConfigParser.ConfigParser()
    conf.set('DEFAULT', 'test', 1)
    conf.write(f)

我会得到文件:

[DEFAULT]
test = 1

但是我怎样才能在[DEFAULT] 部分中获取带有 cmets 的文件,例如:

[DEFAULT]
; test comment
test = 1

我知道我可以通过以下方式将代码写入文件:

import ConfigParser
with open('./config.ini', 'w') as f:
    conf = ConfigParser.ConfigParser()
    conf.set('DEFAULT', 'test', 1)
    conf.write(f)
    f.write('; test comment') # but this gets printed after the section key-value pairs

ConfigParser 有可能吗?而且我不想尝试其他模块,因为我需要让我的程序尽可能地保持“库存”。

【问题讨论】:

  • 在考虑使用 ConfigParser 编写配置文件后,我决定使用旧的标准文件接口 f = open('test.ini', 'w'); f.write('blabla') 编写我的文件,因为 ConfigParser 模块甚至没有按预定义的顺序写入(因为它使用字典,甚至虽然其中一个例子表明写作是按某种顺序进行的:python docs)
  • 如果你还在,我建议你写一个简短的答案,并将其标记为已接受。即使在此评论之后,我也阅读了建议的答案并得出了相同的结论......但花了我一段时间,我什至投票赞成你选择的解决方案......

标签: python configparser


【解决方案1】:

您可以创建以 # 或 ; 开头的变量人物:

conf.set('default_settings', '; comment here', '')
conf.set('default_settings', 'test', 1)

创建的conf文件是

    [default_settings]
    ; comment here = 
    test = 1

ConfigParser.read 函数不会解析第一个值

config = ConfigParser.ConfigParser()
config.read('config.ini')
print config.items('default_settings')

给予

[('test','1')]

【讨论】:

  • 很丑,尾随=
  • 这可能是使用 ConfigParser 的最好也是唯一的方法。谢谢
  • 你可以去掉后面的=。当你想写评论时,你只需在调用set 方法时省略第三个参数。否则,您将为其分配一个空字符串,这会导致不需要的尾随 =
  • 如果set方法没有接收到第三个参数,则默认为None。例如,如果我们有conf.set('DEFAULT', '; comment'),我们会得到; comment = None
【解决方案2】:

如果您的版本 >= 2.7,则可以使用 allow_no_value 选项

这个sn-p:

import ConfigParser

config = ConfigParser.ConfigParser(allow_no_value=True)
config.add_section('default_settings')
config.set('default_settings', '; comment here')
config.set('default_settings', 'test', 1)
with open('config.ini', 'w') as fp:
    config.write(fp)


config = ConfigParser.ConfigParser(allow_no_value=True)
config.read('config.ini')
print config.items('default_settings')

会像这样创建一个ini文件:

[default_settings]
; comment here
test = 1

【讨论】:

  • 附带说明,只要您不尝试在“DEFAULT”部分中编写 cmets,此方法就可以工作 - 在 write 函数中有一个检查以避免写入“= None”,但仅当不写出“默认”部分时。
  • 好点。幸运的是,在 Python 3.6 中,configparser 模块没有这种奇怪的行为。因此,config = configparser.ConfigParser({"; comment": None}, allow_no_value=True) 在默认部分插入注释,没有任何尾随 = None。为了保证输出的正确排序,需要collections.OrderedDict(而不是我的示例中的dict)。
  • 此选项仅在您创建新文件的情况下有效。如果您正在使用 cmets 编辑以前的文件,它们将全部擦除:/
【解决方案3】:

您也可以使用ConfigUpdater。它有更多方便的选项以微创方式更新配置文件。

你基本上会这样做:

from configupdater import ConfigUpdater

updater = ConfigUpdater()
updater.add_section('DEFAULT')
updater.set('DEFAULT', 'test', 1)
updater['DEFAULT']['test'].add_before.comment('test comment', comment_prefix=';')
with open('./config.ini', 'w') as f:
    updater.write(f)

【讨论】:

    【解决方案4】:

    3.7 更新

    我最近一直在与 configparser 打交道,偶然发现了这篇文章。想我会用与 3.7 相关的信息来更新它。

    示例 1:

    config = configparser.ConfigParser(allow_no_value=True)
    config.set('SECTION', '; This is a comment.', None)
    

    示例 2:

    config = configparser.ConfigParser(allow_no_value=True)
    config['SECTION'] = {'; This is a comment':None, 'Option':'Value')
    

    示例 3:如果您想保持字母大小写不变(默认是将所有选项:值对转换为小写)

    config = configparser.ConfigParser(allow_no_value=True)
    config.optionxform = str
    config.set('SECTION', '; This Comment Will Keep Its Original Case', None)
    

    其中“SECTION”是您要添加评论的区分大小写的部分名称。使用“None”(无引号)而不是空字符串 ('') 将允许您设置注释而不留下尾随的“=”。

    【讨论】:

      【解决方案5】:

      上述问题的怪异解决方案 :) 注意 有一个 副作用看看是否适合你

      config = configparser.ConfigParser(comment_prefixes='///')
      config.set('section', '# cmt', 'comment goes here')
      

      configparse 会将 cmets 视为变量,但真正的软件不会。 这甚至可以在读取相同的 ini 文件后保留 cmets,这是一个真正的游戏规则改变者(消失的 cmets 太可怕了):) 你不需要做allow_no_value=True 来允许空值,只是次要视觉糖果:)

      所以 ini 文件看起来像:

      [section]
      # cmt = comment goes here
      

      这几乎可以完成工作:) 请确保使用一个永远不会出现在您的 ini 文件中的字符串来初始化 comment_prefixes,以防万一

      这在 3.9 中对我有用。

      副作用 关于编写已经存在的 cmets。它们不会消失,这是正常的默认值,但会转换为类似的形式 # first = <remaining>,其中 first - 评论的第一个词,remaining - 评论的剩余部分,这会改变文件的外观,所以要小心...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-05
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 2012-03-18
        • 1970-01-01
        相关资源
        最近更新 更多