Wie lese und schreibe ich eine INI-Datei mit Python3?


117

Ich muss mit Python3 eine INI- Datei lesen, schreiben und erstellen .

FILE.INI

default_path = "/path/name/"
default_file = "file.txt"

Python-Datei:

#    Read file and and create if it not exists
config = iniFile( 'FILE.INI' )

#    Get "default_path"
config.default_path

#    Print (string)/path/name
print config.default_path

#    Create or Update
config.append( 'default_path', 'var/shared/' )
config.append( 'default_message', 'Hey! help me!!' )

AKTUALISIERTE DATEI.INI

default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"



Eine richtige INI-Datei benötigt eine Abschnittsüberschrift wie [foobar].
Martin Thoma

Antworten:


147

Dies kann etwas sein, mit dem man beginnen kann:

import configparser

config = configparser.ConfigParser()
config.read('FILE.INI')
print(config['DEFAULT']['path'])     # -> "/path/name/"
config['DEFAULT']['path'] = '/var/shared/'    # update
config['DEFAULT']['default_message'] = 'Hey! help me!!'   # create

with open('FILE.INI', 'w') as configfile:    # save
    config.write(configfile)

Weitere Informationen finden Sie in der offiziellen configparser-Dokumentation .


4
Gibt an, configparser.MissingSectionHeaderErrorwenn bereitgestellte Beispieldateien ohne die richtigen Abschnittsüberschriften verwendet werden.
Jaakko

81

Hier ist ein vollständiges Beispiel zum Lesen, Aktualisieren und Schreiben.

Eingabedatei, test.ini

[section_a]
string_val = hello
bool_val = false
int_val = 11
pi_val = 3.14

Arbeitscode.

try:
    from configparser import ConfigParser
except ImportError:
    from ConfigParser import ConfigParser  # ver. < 3.0

# instantiate
config = ConfigParser()

# parse existing file
config.read('test.ini')

# read values from a section
string_val = config.get('section_a', 'string_val')
bool_val = config.getboolean('section_a', 'bool_val')
int_val = config.getint('section_a', 'int_val')
float_val = config.getfloat('section_a', 'pi_val')

# update existing value
config.set('section_a', 'string_val', 'world')

# add a new section and some values
config.add_section('section_b')
config.set('section_b', 'meal_val', 'spam')
config.set('section_b', 'not_found_val', '404')

# save to a file
with open('test_update.ini', 'w') as configfile:
    config.write(configfile)

Ausgabedatei test_update.ini

[section_a]
string_val = world
bool_val = false
int_val = 11
pi_val = 3.14

[section_b]
meal_val = spam
not_found_val = 404

Die ursprüngliche Eingabedatei bleibt unberührt.


Auf meinem Python 3.7-System musste die Zeile "config.set ('section_b', 'not_found_val', 404)" in "config.set ('section_b', 'not_found_val', str (404))" geändert werden, da die Parameter für "set" müssen Zeichenfolgen sein. Exzellentes Beispiel, danke!
Herr Ed

Es sieht so aus, als ob die read Methode jetzt eine Liste der gelesenen Dateien / Dateien zurückgibt, aber nicht den Inhalt
YTerle


5

Der Standard ConfigParsererfordert normalerweise den Zugriff über config['section_name']['key'], was keinen Spaß macht. Eine kleine Änderung kann den Attributzugriff ermöglichen:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

AttrDictist eine abgeleitete Klasse, dictdie den Zugriff sowohl über Wörterbuchschlüssel als auch über den Attributzugriff ermöglichta.x is a['x']

Wir können diese Klasse verwenden in ConfigParser:

config = configparser.ConfigParser(dict_type=AttrDict)
config.read('application.ini')

und jetzt kommen wir application.inimit:

[general]
key = value

wie

>>> config._sections.general.key
'value'

6
netter Trick, aber die Benutzer dieser Methode sollten darauf achten, dass beim Zugriff auf config._sections.general.key = "3"diese Weise der interne Wert der Konfigurationsoption nicht geändert wird und daher nur für den schreibgeschützten Zugriff verwendet werden kann. Wenn nach dem .read()Befehl die Konfiguration erweitert oder geändert wird (Optionen hinzufügen, Wertepaare für einige Abschnitte, -> Interpolation, was sehr wichtig sein kann), sollte diese Zugriffsmethode nicht verwendet werden! Auch jeder config._sections["section"]["opt"]private Zugriff umgeht die Interpolation und gibt die Rohwerte zurück!
Gabriel

5

ConfigObj ist eine gute Alternative zu ConfigParser, die viel mehr Flexibilität bietet:

  • Verschachtelte Abschnitte (Unterabschnitte) auf jeder Ebene
  • Werte auflisten
  • Mehrere Zeilenwerte
  • String-Interpolation (Substitution)
  • Integriert in ein leistungsstarkes Validierungssystem, das wiederholte Abschnitte zur automatischen Typprüfung / -konvertierung umfasst und Standardwerte zulässt
  • Beim Schreiben von Konfigurationsdateien behält ConfigObj alle Kommentare und die Reihenfolge der Mitglieder und Abschnitte bei
  • Viele nützliche Methoden und Optionen für die Arbeit mit Konfigurationsdateien (wie die 'reload'-Methode)
  • Volle Unicode-Unterstützung

Es hat einige Nachteile:

  • Sie können das Trennzeichen nicht festlegen, es muss =… sein ( Pull-Anfrage )
  • Sie können keine leeren Werte haben, Sie können es auch, aber sie sehen gut aus: fuabr =statt nur, fubarwas seltsam und falsch aussieht.

1
Sardathrion ist richtig, ConfigObj ist der richtige Weg, wenn Sie die Kommentare in der Datei und die Abschnittsreihenfolge wie in der Originaldatei beibehalten möchten. ConfigParser löscht nur Ihre Kommentare und verschlüsselt irgendwann auch die Reihenfolge.
Stehen Sie

1

Inhalt in meiner Datei backup_settings.ini

[Settings]
year = 2020

Python-Code zum Lesen

import configparser
config = configparser.ConfigParser()
config.read('backup_settings.ini') #path of your .ini file
year = config.get("Settings","year") 
print(year)

zum Schreiben oder Aktualisieren

from pathlib import Path
import configparser
myfile = Path('backup_settings.ini')  #Path of your .ini file
config.read(myfile)
config.set('Settings', 'year','2050') #Updating existing entry 
config.set('Settings', 'day','sunday') #Writing new entry
config.write(myfile.open("w"))

Ausgabe

[Settings]
year = 2050
day = sunday
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.