Python: Comment enregistreriez-vous un simple fichier de configuration / configuration?

101

Je ne me soucie pas si c'est JSON, pickle, YAMLou autre chose.

Toutes les autres implémentations que j'ai vues ne sont pas compatibles en aval, donc si j'ai un fichier de configuration, ajoutez une nouvelle clé dans le code, puis chargez ce fichier de configuration, il plantera simplement.

Existe-t-il un moyen simple de le faire?

user1438098
la source
1
Je pense que l'utilisation du .iniformat similaire du configparsermodule devrait faire ce que vous voulez.
Bakuriu
14
aucune chance de choisir ma réponse comme correcte?
Graeme Stuart

Réponses:

188

Fichiers de configuration en python

Il existe plusieurs façons de procéder selon le format de fichier requis.

ConfigParser [format .ini]

J'utiliserais l' approche standard du configparser à moins qu'il n'y ait des raisons impérieuses d'utiliser un format différent.

Écrivez un fichier comme ceci:

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

Le format de fichier est très simple avec des sections marquées entre crochets:

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

Les valeurs peuvent être extraites du fichier comme ceci:

# 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 [format .json]

Les données JSON peuvent être très complexes et ont l'avantage d'être hautement portables.

Ecrire des données dans un fichier:

import json

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

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

Lire les données d'un fichier:

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

Un exemple de base YAML est fourni dans cette réponse . Plus de détails peuvent être trouvés sur le site Web de pyYAML .

Graeme Stuart
la source
8
en python 3 from configparser import ConfigParser config = ConfigParser()
user3148949
12

Exemple de ConfigParser Basic

Le fichier peut être chargé et utilisé comme ceci:

#!/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?

quelles sorties

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

Comme vous pouvez le voir, vous pouvez utiliser un format de données standard facile à lire et à écrire. Des méthodes comme getboolean et getint vous permettent d'obtenir le type de données au lieu d'une simple chaîne.

Configuration d'écriture

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

résulte en

[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

Exemple XML Basic

Semble ne pas être utilisé du tout pour les fichiers de configuration par la communauté Python. Cependant, l'analyse / l'écriture de XML est facile et il existe de nombreuses possibilités pour le faire avec Python. L'un est 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)

où le config.xml pourrait ressembler à ceci

<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>
scre_www
la source
Beau code / exemples. Commentaire mineur - votre exemple YAML n'utilise pas YAML mais un format de style INI.
Eric Kramer
Il convient de noter qu'au moins la version python 2 de ConfigParser convertira silencieusement la liste stockée en chaîne lors de la lecture. C'est à dire. CP.set ('section', 'option', [1,2,3]) après avoir sauvegardé et lu la configuration sera CP.get ('section', 'option') => '1, 2, 3'
Gnudiff
10

Si vous souhaitez utiliser quelque chose comme un fichier INI pour conserver les paramètres, envisagez d'utiliser configparser qui charge les paires clé / valeur à partir d'un fichier texte et peut facilement réécrire dans le fichier.

Le fichier INI a le format:

[Section]
key = value
key with spaces = somevalue
Tadgh
la source
2

Enregistrez et chargez un dictionnaire. Vous aurez des clés, des valeurs et un nombre arbitraire de paires de clés et de valeurs arbitraires.

Dmitri
la source
puis-je utiliser le refactoring avec ça?
Lore
1

Essayez d'utiliser 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"
Richie Bendall
la source
-2

essayez d'utiliser cfg4py :

  1. Conception hiérarchique, prise en charge de plusieurs environnements, afin de ne jamais gâcher les paramètres de développement avec les paramètres du site de production.
  2. Achèvement du code. Cfg4py convertira votre yaml en une classe python, puis la complétion de code est disponible pendant que vous tapez votre code.
  3. beaucoup plus..

AVERTISSEMENT: je suis l'auteur de ce module

Aaron
la source