2009-02-19 2 views
1

На основе модуля ConfigParser, как я могу отфильтровать и выкинуть каждый комментарий из ini-файла?Python - ConfigParser бросает комментарии

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read("sample.cfg") 

for section in config.sections(): 
    print section 
    for option in config.options(section): 
     print option, "=", config.get(section, option) 

eg. в ини файле ниже выше базового сценария печатает дополнительные комментарии линии, а также как:

something = 128  ; comment line1 
         ; further comments 
         ; one more line comment 

Что мне нужно, это имея только названия разделов и чистые пары ключ-значение внутри них без каких-либо комментариев. Поддерживает ли ConfigParser это как-то или я должен использовать regexp ... или? Cheers

+1

Что означает «выброс»? Просьба представить четкое заявление о том, что вы действительно пытаетесь сделать - зачем вам «выкидывать» данные из файла? Куда он идет? Что осталось? –

ответ

5

согласно docs линии, начинающиеся с ; или # будут игнорироваться. это не похоже на то, что ваш формат удовлетворяет этому требованию. можете ли вы каким-либо образом изменить формат вашего входного файла?

редактировать: так как вы не можете изменить свои входные файлы, я бы предложил предварительно разборе их с чем-то вдоль линий:

tmp_fname = 'config.tmp' 
with open(config_file) as old_file: 
    with open(tmp_fname, 'w') as tmp_file: 
     tmp_file.writelines(i.replace(';', '\n;') for i in old_lines.readlines()) 
# then use tmp_fname with ConfigParser 

, очевидно, если точка с запятой присутствует в настройках вы будете иметь чтобы быть более креативным.

2

Похоже, ваши комментарии не в строках, которые начинаются с комментарием. Он должен работать, если лидером комментария является первый символ на линии.

+0

Спасибо, но, к сожалению, мне не разрешено изменять входной файл ini. В этом формате ini-файла, поскольку я заметил, что все строки комментариев добавлены к части значения последнего ключа - кроме первой строки комментария (справа после значения), которая действительно падает. – 2009-02-19 11:53:02

+0

На самом деле моя задача - сравнить два ini-файла (каждая значимая часть, кроме комментариев) – 2009-02-19 11:54:10

+0

Тогда вам, вероятно, придется создать временный файл и/или использовать ConfigParser.readfp(), чтобы отказаться от комментариев. – sykora

3

Лучший способ это написать commentless file подкласс:

class CommentlessFile(file): 
    def readline(self): 
     line = super(CommentlessFile, self).readline() 
     if line: 
      line = line.split(';', 1)[0].strip() 
      return line + '\n' 
     else: 
      return '' 

Вы могли бы использовать его, то с ConfigParser (ваш код):

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.readfp(CommentlessFile("sample.cfg")) 

for section in config.sections(): 
    print section 
    for option in config.options(section): 
     print option, "=", config.get(section, option) 
+0

Я думаю, что там есть небольшая опечатка, она должна быть супер (CommentlessFile, self) .readline(), а не CommentRemover. – sykora

+0

@sykora: Я установил это через 5 секунд после первого сообщения :) – nosklo

1

Как сказал доктор: «(для обратной совместимости , только, запускает встроенный комментарий, а # нет.) «Так используйте»; а не «#» для встроенных комментариев. Это хорошо работает для меня.

0

Python 3 поставляется со встроенным решением: класс configparser.RawConfigParser имеет аргумент конструктора inline_comment_prefixes. Пример:

class MyConfigParser(configparser.RawConfigParser): 
    def __init__(self): 
     configparser.RawConfigParser.__init__(self, inline_comment_prefixes=('#', ';')) 
Смежные вопросы