Como ler e escrever arquivo INI com Python3?

117

Eu preciso ler, escrever e criar um arquivo INI com Python3.

FILE.INI

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

Arquivo 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 ATUALIZADO

default_path    = "var/shared/"
default_file    = "file.txt"
default_message = "Hey! help me!!"
Olaf
fonte
5
Que tal docs.python.org/library/configparser.html ?
Algum programador cara de
2
Na verdade, que tal stackoverflow.com/a/3220891/716118 ?
voithos
um arquivo ini adequado precisa de um título de seção como [foobar].
Martin Thoma
consulte também stackoverflow.com/questions/19078170/…
Graeme Stuart

Respostas:

147

Isso pode ser algo para começar:

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)

Você pode encontrar mais na documentação oficial do configparser .

Rik Poggi
fonte
4
Fornece configparser.MissingSectionHeaderErrorao usar arquivos de exemplo fornecidos sem os cabeçalhos de seção apropriados.
Jaakko
81

Aqui está um exemplo completo de leitura, atualização e gravação.

Arquivo de entrada, test.ini

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

Código de trabalho.

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)

Arquivo de saída, 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

O arquivo de entrada original permanece intocado.

Agostino
fonte
No meu sistema Python 3.7, a linha "config.set ('section_b', 'not_found_val', 404)" teve que ser alterada para "config.set ('section_b', 'not_found_val', str (404))" porque o os parâmetros para "definir" devem ser strings. Excelente exemplo, obrigado!
Sr. Ed
parece que o read método agora retorna uma lista de arquivos / arquivos lidos, mas não o conteúdo
YTerle
5

O padrão ConfigParsernormalmente requer acesso via config['section_name']['key'], o que não é divertido. Uma pequena modificação pode fornecer acesso ao atributo:

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

AttrDicté uma classe derivada da dictqual permite o acesso por meio de chaves de dicionário e acesso de atributo: isso significaa.x is a['x']

Podemos usar esta classe em ConfigParser:

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

e agora temos application.inicom:

[general]
key = value

Como

>>> config._sections.general.key
'value'
Robert Siemer
fonte
6
bom truque, mas os usuários deste método devem ter cuidado, que ao acessar assim config._sections.general.key = "3"não está alterando o valor interno da opção de configuração e, portanto, só pode ser usado para acesso somente leitura. Se após o .read()comando a configuração for estendida ou alterada (adicionar opções, pares de valores para algumas seções, -> que faz interpolação que pode ser muito importante), este método de acesso não deve ser usado! Além disso, qualquer acesso config._sections["section"]["opt"]privado contorna a interpolação e retorna os valores brutos!
Gabriel
5

O ConfigObj é uma boa alternativa ao ConfigParser, que oferece muito mais flexibilidade:

  • Seções aninhadas (subseções), em qualquer nível
  • Valores de lista
  • Vários valores de linha
  • Interpolação de string (substituição)
  • Integrado com um sistema de validação poderoso, incluindo verificação automática de tipo / conversão de seções repetidas e permitindo valores padrão
  • Ao gravar arquivos de configuração, o ConfigObj preserva todos os comentários e a ordem dos membros e seções
  • Muitos métodos e opções úteis para trabalhar com arquivos de configuração (como o método 'reload')
  • Suporte total a Unicode

Tem algumas desvantagens:

  • Você não pode definir o delimitador, ele tem que ser =... ( solicitação de pull )
  • Você não pode ter valores vazios, bem, você pode, mas eles parecem amados: em fuabr =vez de apenas o fubarque parece estranho e errado.
Sardathrion - contra o abuso de SE
fonte
1
Sardathrion está certo, ConfigObj é o caminho a percorrer se você quiser manter os comentários no arquivo e a ordem das seções como no arquivo original. O ConfigParser apenas limpará seus comentários e também embaralhará a ordem em algum ponto.
Surge
1

conteúdo no meu arquivo backup_settings.ini

[Settings]
year = 2020

código python para leitura

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

para escrever ou atualizar

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

resultado

[Settings]
year = 2050
day = sunday
RK-Muscles God
fonte