¿Cómo leer y escribir un archivo INI con Python3?

118

Necesito leer, escribir y crear un INI archivo con Python3.

FILE.INI

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

Archivo 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 ACTUALIZADO

default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"
Olaf
fuente
5
¿Qué tal docs.python.org/library/configparser.html ?
Un tipo programador
2
De hecho, ¿qué tal stackoverflow.com/a/3220891/716118 ?
voithos
un archivo ini adecuado necesita un encabezado de sección como [foobar].
Martin Thoma
ver también stackoverflow.com/questions/19078170/…
Graeme Stuart

Respuestas:

148

Esto puede ser algo para comenzar:

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)

Puede encontrar más en la documentación oficial de configparser .

Rik Poggi
fuente
4
Da configparser.MissingSectionHeaderErrorcuando se utilizan archivos de ejemplo proporcionados sin los encabezados de sección adecuados.
Jaakko
81

Aquí hay un ejemplo completo de lectura, actualización y escritura.

Archivo de entrada, test.ini

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

Código de trabajo.

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)

Archivo de salida, 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

El archivo de entrada original permanece intacto.

Agostino
fuente
En mi sistema Python 3.7, la línea "config.set ('section_b', 'not_found_val', 404)" tuvo que cambiarse a "config.set ('section_b', 'not_found_val', str (404))" porque el los parámetros para "establecer" tienen que ser cadenas. Excelente ejemplo, gracias!
Mr Ed
parece que el read método ahora devuelve una lista de archivos / archivos leídos, pero no el contenido
YTerle
5

El estándar ConfigParsernormalmente requiere acceso a través de config['section_name']['key'], lo cual no es divertido. Una pequeña modificación puede ofrecer acceso a atributos:

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

AttrDictes una clase derivada de la dictcual permite el acceso a través de claves de diccionario y acceso a atributos: eso significaa.x is a['x']

Podemos usar esta clase en ConfigParser:

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

y ahora llegamos application.inicon:

[general]
key = value

como

>>> config._sections.general.key
'value'
Robert Siemer
fuente
6
Buen truco, pero los usuarios de este método deben tener cuidado, que al acceder así config._sections.general.key = "3"no se cambia el valor interno de la opción de configuración y por lo tanto solo se puede usar para acceso de solo lectura. Si después del .read()comando la configuración se amplía o cambia (agregue opciones, pares de valores para algunas secciones, -> que hace interpolación, lo cual podría ser muy importante), ¡este método de acceso no debe usarse! ¡Además, cualquier acceso al config._sections["section"]["opt"]que sea privado elude la interpolación y devuelve los valores sin procesar!
Gabriel
5

ConfigObj es una buena alternativa a ConfigParser que ofrece mucha más flexibilidad:

  • Secciones anidadas (subsecciones), a cualquier nivel
  • Lista de valores
  • Valores de varias líneas
  • Interpolación de cadenas (sustitución)
  • Integrado con un potente sistema de validación que incluye la verificación automática de tipos / conversión de secciones repetidas y permite valores predeterminados
  • Al escribir archivos de configuración, ConfigObj conserva todos los comentarios y el orden de los miembros y las secciones
  • Muchos métodos y opciones útiles para trabajar con archivos de configuración (como el método 'recargar')
  • Soporte completo de Unicode

Tiene algunos inconvenientes:

  • No puede establecer el delimitador, tiene que ser =... ( solicitud de extracción )
  • No puede tener valores vacíos, bueno, puede, pero se ven gustados: en fuabr =lugar de simplemente lo fubarque se ve extraño e incorrecto.
Sardathrion - contra el abuso SE
fuente
1
Sardathrion tiene razón, ConfigObj es el camino a seguir si desea mantener los comentarios en el archivo y el orden de las secciones como en el archivo original. ConfigParser simplemente borrará sus comentarios y también codificará el orden en algún momento.
Levántate el
2

contenido en mi archivo backup_settings.ini

[Settings]
year = 2020

código python para leer

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

para escribir o actualizar

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

salida

[Settings]
year = 2050
day = sunday
Dios de los músculos RK
fuente
¡Esto funciona como un encanto y está limpio!
Rodrigo.A92