Come leggere e scrivere file INI con Python3?


118

Ho bisogno di leggere, scrivere e creare un file INI con Python3.

FILE.INI

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

File Python:

#    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!!' )

FILE.INI AGGIORNATO

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


2
In effetti, che ne dici di stackoverflow.com/a/3220891/716118 ?
voithos

un file ini corretto necessita di un'intestazione di sezione come [foobar].
Martin Thoma

Risposte:


148

Questo può essere qualcosa con cui iniziare:

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)

Puoi trovare di più nella documentazione ufficiale del configparser .


4
Fornisce configparser.MissingSectionHeaderErrorquando si utilizzano file di esempio forniti senza le intestazioni di sezione appropriate.
Jaakko

81

Ecco un esempio completo di lettura, aggiornamento e scrittura.

File di input, test.ini

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

Codice funzionante.

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)

File di output, 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

Il file di input originale rimane intatto.


Sul mio sistema Python 3.7, la riga "config.set ('section_b', 'not_found_val', 404)" doveva essere cambiata in "config.set ('section_b', 'not_found_val', str (404))" perché il i parametri per "set" devono essere stringhe. Ottimo esempio, grazie!
Mr Ed

sembra che il read metodo ora restituisca un elenco di file / file letti, ma non il contenuto
YTerle


5

Lo standard ConfigParsernormalmente richiede l'accesso tramite config['section_name']['key'], il che non è divertente. Una piccola modifica può fornire l'accesso agli attributi:

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

AttrDictè una classe derivata dalla dictquale consente l'accesso tramite sia le chiavi del dizionario che l'accesso agli attributi: ciò significaa.x is a['x']

Possiamo usare questa classe in ConfigParser:

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

e ora arriviamo application.inicon:

[general]
key = value

come

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

6
bel trucco, ma gli utenti di questo metodo dovrebbero fare attenzione, che quando accedono in config._sections.general.key = "3"questo modo non cambia il valore interno dell'opzione di configurazione e quindi può essere utilizzato solo per l'accesso in sola lettura. Se dopo il .read()comando la configurazione viene estesa o modificata (aggiungi opzioni, coppie di valori per alcune sezioni, -> che fa l'interpolazione che potrebbe essere molto importante) questo metodo di accesso non dovrebbe essere usato! Anche qualsiasi accesso config._sections["section"]["opt"]privato elude l'interpolazione e restituisce i valori grezzi!
Gabriel

5

ConfigObj è una buona alternativa a ConfigParser che offre molta più flessibilità:

  • Sezioni nidificate (sottosezioni), a qualsiasi livello
  • Valori dell'elenco
  • Valori di più righe
  • Interpolazione di stringhe (sostituzione)
  • Integrato con un potente sistema di convalida che include il controllo automatico del tipo / sezioni ripetute di conversione e consente valori predefiniti
  • Durante la scrittura dei file di configurazione, ConfigObj conserva tutti i commenti e l'ordine dei membri e delle sezioni
  • Molti metodi e opzioni utili per lavorare con i file di configurazione (come il metodo 'reload')
  • Pieno supporto Unicode

Presenta alcuni inconvenienti:

  • Non puoi impostare il delimitatore, deve essere =... ( richiesta pull )
  • Non puoi avere valori vuoti, beh puoi ma sembrano apprezzati: fuabr =invece di quelli fubarche sembrano strani e sbagliati.

1
Sardathrion ha ragione, ConfigObj è la strada da percorrere se si desidera mantenere i commenti nel file e l'ordine delle sezioni come nel file originale. ConfigParser cancellerà solo i tuoi commenti e ad un certo punto modificherà anche l'ordine.
Alzati l'

2

contenuto nel mio file backup_settings.ini

[Settings]
year = 2020

codice Python per la lettura

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

per la scrittura o l'aggiornamento

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"))

produzione

[Settings]
year = 2050
day = sunday

Funziona come un fascino ed è pulito!
Rodrigo.A92
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.