Mam source.ini jako następujący

[section1]
name = 'xyz'
place = 'abc'

[section2]
....
....

[section3]
....
....

Chcę przeczytać zawartość źródła.ini i kopiować tylko listę sekcji w nowym pliku ini. Oto mój kod robi potrzebne ..

import ConfigParser

Config = ConfigParser.RawConfigParser()
Config.read('source.ini')
sections = ['section1', 'section2']

outputConfig = ConfigParser.RawConfigParser()

with open('destination.ini', 'wb') as fp:
    for each_section in sections:
        fp.write('\n\n['+each_section+']\n')
        for (each_key, each_val) in Config.items(each_section):
            fp.write(each_key+':'+each_val+'\n')

        outputConfig.write(fp)

Dostaję produkcję zgodnie z potrzebami. Moje pytanie brzmi, czy robię to właściwy sposób? Czy jest bardziej elegancki sposób?

0
nick01 14 sierpień 2014, 10:41

2 odpowiedzi

Najlepsza odpowiedź

Tak, twój kod jest nieustanny. Pisze plik wyjściowy dwa razy . Po pierwsze, ręcznie:

fp.write(each_key+':'+each_val+'\n')

I po drugie, za pomocą obiektu RawConfigParser:

outputConfig.write(fp)

Tylko podręcznik jest skuteczny. Wezwanie do outputConfig.write() jest no-op.

Powinniśmy wyeliminować jedną z dwóch metod tworzenia pliku wyjściowego, ale który? Twierdzę, że metoda ręczna powinna zostać usunięta, ponieważ program inaczej nie musi mieć intymnej znajomości formatu pliku .ini.

Ponadto, znajduję swoje użycie each_, aby reprezentować zmienne pętli niepokojące. Może to tylko osobiste preferencje.

Oto jak to naprawił:

import ConfigParser

Config = ConfigParser.RawConfigParser()
Config.read('source.ini')
sections = ['section1', 'section2']

outputConfig = ConfigParser.RawConfigParser()

for section in sections:
    outputConfig.add_section(section)
    for key, val in Config.items(section):
        outputConfig.set(section, key, val)


with open('destination.ini', 'w') as fp:
    outputConfig.write(fp)
1
Robᵩ 15 sierpień 2014, 04:16

Niezależnie od odpowiedzi Rob, może istnieć kilka innych problemów z twoim podejściem. Najpierw używasz RawConfigParser. Jest poprawny w Python 2.x, ale dla 3.x jest uważany za dziedzictwo, a {X1}} zostanie zalecana.

Ale IMHO, głównym problemem jest to, że moduł configparser będzie usunąć komentarz z pliku, jeśli masz trochę i chcesz je zachować. Oto wariant przy użyciu REGEX, który utrzyma komentarze, pod warunkiem, że są albo na początku pliku, albo po poprawie [section]:

import re

sections = ['section1', 'section2']
rxsect = re.compile('^\s*\[\s*(\w+)\s*\]')
with open('source.init') as fin, open('destination.ini', 'w') as fout:
    copy = True
    for line in fin:
        m = rxsect.match(line)
        if m:
            copy = m.group(1) in sections
        if copy:
            n = fout.write(line)

Oczywiście, jeśli uwagi nie są obawami, odpowiedź Roba jest lepsza, ponieważ plik jest analizowany, a błędy składniowe zostaną wykryte, podczas gdy moje zakłada, że plik jest poprawny.

1
Serge Ballesta 14 sierpień 2014, 11:54