web-dev-qa-db-fra.com

Python: Comment voulez-vous enregistrer un simple fichier de paramètres / config?

Peu m'importe si c'est JSON, pickle, YAML ou autre chose.

Toutes les autres implémentations que j'ai vues ne sont pas compatibles avec la transmission. Par conséquent, si j'ai un fichier de configuration, ajoutez une nouvelle clé dans le code, puis chargez ce fichier de configuration, il se plantera.

Y at-il un moyen simple de faire cela?

77
user1438098

Fichiers de configuration en python

Il existe plusieurs façons de procéder en fonction du format de fichier requis.

ConfigParser [format .ini]

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

Ecrivez un fichier comme ceci:

from ConfigParser import SafeConfigParser

config = SafeConfigParser()
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, les sections étant indiquées entre crochets:

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

Les valeurs peuvent être extraites du fichier de la manière suivante:

from ConfigParser import SafeConfigParser

config = SafeConfigParser()
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 présentent l'avantage d'être extrêmement portables.

Écrire 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 de YAML est fourni dans cette réponse . Plus de détails peuvent être trouvés sur le site web pyYAML .

152
Graeme Stuart

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

Le fichier INI a le format suivant:

[Section]
key = value
key with spaces = somevalue
10
Tadgh

exemple de base de ConfigParser

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?

qui sort

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 constater, vous pouvez utiliser un format de données standard facile à lire et à écrire. Des méthodes telles que getboolean et getint vous permettent d'obtenir le type de données au lieu d'une simple chaîne.

Écriture de la configuration

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

Ne semble pas du tout être utilisé pour les fichiers de configuration par la communauté Python. Cependant, analyser/écrire du XML est simple et il y a beaucoup de possibilités pour le faire avec Python. One is 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 fichier 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>
9
scre_www

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"
1
Richie Bendall

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

1
dmitri