Python: come salveresti un semplice file di impostazioni / configurazione?


101

Non mi importa se si tratta di JSON, pickle, YAML, o qualsiasi altra cosa.

Tutte le altre implementazioni che ho visto non sono compatibili con le versioni successive, quindi se ho un file di configurazione, aggiungi una nuova chiave nel codice, quindi carica il file di configurazione, si bloccherà.

C'è un modo semplice per farlo?


1
Credo che l'uso del .iniformato simile al configparsermodulo dovrebbe fare quello che vuoi.
Bakuriu

14
qualche possibilità di selezionare la mia risposta come corretta?
Graeme Stuart

Risposte:


188

File di configurazione in python

Ci sono diversi modi per farlo a seconda del formato di file richiesto.

ConfigParser [formato .ini]

Vorrei utilizzare l' approccio configparser standard a meno che non ci fossero validi motivi per utilizzare un formato diverso.

Scrivi un file in questo modo:

# python 2.x
# from ConfigParser import SafeConfigParser
# config = SafeConfigParser()

# python 3.x
from configparser import ConfigParser
config = ConfigParser()

config.read('config.ini')
config.add_section('main')
config.set('main', 'key1', 'value1')
config.set('main', 'key2', 'value2')
config.set('main', 'key3', 'value3')

with open('config.ini', 'w') as f:
    config.write(f)

Il formato del file è molto semplice con sezioni segnate tra parentesi quadre:

[main]
key1 = value1
key2 = value2
key3 = value3

I valori possono essere estratti dal file in questo modo:

# python 2.x
# from ConfigParser import SafeConfigParser
# config = SafeConfigParser()

# python 3.x
from configparser import ConfigParser
config = ConfigParser()

config.read('config.ini')

print config.get('main', 'key1') # -> "value1"
print config.get('main', 'key2') # -> "value2"
print config.get('main', 'key3') # -> "value3"

# getfloat() raises an exception if the value is not a float
a_float = config.getfloat('main', 'a_float')

# getint() and getboolean() also do this for their respective types
an_int = config.getint('main', 'an_int')

JSON [formato .json]

I dati JSON possono essere molto complessi e hanno il vantaggio di essere altamente portabili.

Scrivi i dati in un file:

import json

config = {'key1': 'value1', 'key2': 'value2'}

with open('config.json', 'w') as f:
    json.dump(config, f)

Leggere i dati da un file:

import json

with open('config.json', 'r') as f:
    config = json.load(f)

#edit the data
config['key3'] = 'value3'

#write it back to the file
with open('config.json', 'w') as f:
    json.dump(config, f)

YAML

In questa risposta viene fornito un esempio YAML di base . Maggiori dettagli possono essere trovati sul sito pyYAML .


8
in python 3 from configparser import ConfigParser config = ConfigParser()
user3148949

12

ConfigParser Basic esempio

Il file può essere caricato e utilizzato in questo modo:

#!/usr/bin/env python

import ConfigParser
import io

# Load the configuration file
with open("config.yml") as f:
    sample_config = f.read()
config = ConfigParser.RawConfigParser(allow_no_value=True)
config.readfp(io.BytesIO(sample_config))

# List all contents
print("List all contents")
for section in config.sections():
    print("Section: %s" % section)
    for options in config.options(section):
        print("x %s:::%s:::%s" % (options,
                                  config.get(section, options),
                                  str(type(options))))

# Print some contents
print("\nPrint some contents")
print(config.get('other', 'use_anonymous'))  # Just get the value
print(config.getboolean('other', 'use_anonymous'))  # You know the datatype?

quali uscite

List all contents
Section: mysql
x host:::localhost:::<type 'str'>
x user:::root:::<type 'str'>
x passwd:::my secret password:::<type 'str'>
x db:::write-math:::<type 'str'>
Section: other
x preprocessing_queue:::["preprocessing.scale_and_center",
"preprocessing.dot_reduction",
"preprocessing.connect_lines"]:::<type 'str'>
x use_anonymous:::yes:::<type 'str'>

Print some contents
yes
True

Come puoi vedere, puoi utilizzare un formato dati standard facile da leggere e scrivere. Metodi come getboolean e getint consentono di ottenere il tipo di dati invece di una semplice stringa.

Configurazione di scrittura

import os
configfile_name = "config.yaml"

# Check if there is already a configurtion file
if not os.path.isfile(configfile_name):
    # Create the configuration file as it doesn't exist yet
    cfgfile = open(configfile_name, 'w')

    # Add content to the file
    Config = ConfigParser.ConfigParser()
    Config.add_section('mysql')
    Config.set('mysql', 'host', 'localhost')
    Config.set('mysql', 'user', 'root')
    Config.set('mysql', 'passwd', 'my secret password')
    Config.set('mysql', 'db', 'write-math')
    Config.add_section('other')
    Config.set('other',
               'preprocessing_queue',
               ['preprocessing.scale_and_center',
                'preprocessing.dot_reduction',
                'preprocessing.connect_lines'])
    Config.set('other', 'use_anonymous', True)
    Config.write(cfgfile)
    cfgfile.close()

risultati in

[mysql]
host = localhost
user = root
passwd = my secret password
db = write-math

[other]
preprocessing_queue = ['preprocessing.scale_and_center', 'preprocessing.dot_reduction', 'preprocessing.connect_lines']
use_anonymous = True

Esempio di XML Basic

Sembra non essere utilizzato affatto per i file di configurazione dalla comunità Python. Tuttavia, l'analisi / scrittura di XML è facile e ci sono molte possibilità per farlo con Python. Uno è BeautifulSoup:

from BeautifulSoup import BeautifulSoup

with open("config.xml") as f:
    content = f.read()

y = BeautifulSoup(content)
print(y.mysql.host.contents[0])
for tag in y.other.preprocessing_queue:
    print(tag)

dove il file config.xml potrebbe apparire così

<config>
    <mysql>
        <host>localhost</host>
        <user>root</user>
        <passwd>my secret password</passwd>
        <db>write-math</db>
    </mysql>
    <other>
        <preprocessing_queue>
            <li>preprocessing.scale_and_center</li>
            <li>preprocessing.dot_reduction</li>
            <li>preprocessing.connect_lines</li>
        </preprocessing_queue>
        <use_anonymous value="true" />
    </other>
</config>

Bel codice / esempi. Commento minore: il tuo esempio YAML non utilizza YAML ma il formato in stile INI.
Eric Kramer

Va notato che almeno la versione python 2 di ConfigParser convertirà silenziosamente l'elenco memorizzato in stringa durante la lettura. Cioè. CP.set ('section', 'option', [1,2,3]) dopo aver salvato e letto la configurazione sarà CP.get ('section', 'option') => '1, 2, 3'
Gnudiff

10

Se vuoi usare qualcosa come un file INI per contenere le impostazioni, considera l'utilizzo di configparser che carica le coppie di valori chiave da un file di testo e può facilmente riscrivere nel file.

Il file INI ha il formato:

[Section]
key = value
key with spaces = somevalue

2

Salva e carica un dizionario. Avrai chiavi arbitrarie, valori e numero arbitrario di chiavi, coppie di valori.


posso usare il refactoring con questo?
Lore

1

Prova a utilizzare ReadSettings :

from readsettings import ReadSettings
data = ReadSettings("settings.json") # Load or create any json, yml, yaml or toml file
data["name"] = "value" # Set "name" to "value"
data["name"] # Returns: "value"

-2

prova a usare cfg4py :

  1. Design gerarchico, supporto multi-env, quindi non confondere mai le impostazioni di sviluppo con le impostazioni del sito di produzione.
  2. Completamento del codice. Cfg4py convertirà il tuo yaml in una classe python, quindi il completamento del codice è disponibile durante la digitazione del codice.
  3. molti altri..

DISCLAIMER: sono l'autore di questo modulo

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.