Python: Wie würden Sie eine einfache Einstellungs- / Konfigurationsdatei speichern?


99

Mir ist es egal , ob es JSON, pickle, YAML, oder was auch immer.

Alle anderen Implementierungen, die ich gesehen habe, sind nicht vorwärtskompatibel. Wenn ich also eine Konfigurationsdatei habe, einen neuen Schlüssel in den Code einfügen und diese Konfigurationsdatei laden, stürzt sie einfach ab.

Gibt es eine einfache Möglichkeit, dies zu tun?


1
Ich glaube, die Verwendung des .iniähnlichen Formats des configparserModuls sollte das tun, was Sie wollen.
Bakuriu

13
Gibt es eine Chance, meine Antwort als richtig auszuwählen?
Graeme Stuart

Antworten:


186

Konfigurationsdateien in Python

Abhängig vom erforderlichen Dateiformat gibt es verschiedene Möglichkeiten, dies zu tun.

ConfigParser [INI-Format]

Ich würde den Standard- Configparser- Ansatz verwenden, es sei denn, es gibt zwingende Gründe, ein anderes Format zu verwenden.

Schreiben Sie eine Datei wie folgt:

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

Das Dateiformat ist sehr einfach mit Abschnitten in eckigen Klammern:

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

Werte können wie folgt aus der Datei extrahiert werden:

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

JSON-Daten können sehr komplex sein und haben den Vorteil, dass sie sehr portabel sind.

Daten in eine Datei schreiben:

import json

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

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

Daten aus einer Datei lesen:

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 dieser Antwort finden Sie ein grundlegendes YAML-Beispiel . Weitere Details finden Sie auf der pyYAML-Website .


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

12

ConfigParser Basic Beispiel

Die Datei kann wie folgt geladen und verwendet werden:

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

welche Ausgänge

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

Wie Sie sehen, können Sie ein Standarddatenformat verwenden, das leicht zu lesen und zu schreiben ist. Mit Methoden wie getboolean und getint können Sie den Datentyp anstelle einer einfachen Zeichenfolge abrufen.

Konfiguration schreiben

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

führt zu

[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

XML Basic Beispiel

Scheint von der Python-Community überhaupt nicht für Konfigurationsdateien verwendet zu werden. Das Parsen / Schreiben von XML ist jedoch einfach und es gibt viele Möglichkeiten, dies mit Python zu tun. Eines ist 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)

wo die config.xml so aussehen könnte

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

Schöner Code / Beispiele. Kleiner Kommentar - Ihr YAML-Beispiel verwendet kein YAML-Format, sondern ein INI-Format.
Eric Kramer

Es ist zu beachten, dass mindestens die Python 2-Version von ConfigParser die gespeicherte Liste beim Lesen stillschweigend in eine Zeichenfolge konvertiert. Dh. CP.set ('section', 'option', [1,2,3]) nach dem Speichern und Lesen der Konfiguration lautet CP.get ('section', 'option') => '1, 2, 3'
Gnudiff


2

Speichern und laden Sie ein Wörterbuch. Sie haben beliebige Schlüssel, Werte und eine beliebige Anzahl von Schlüssel- und Wertepaaren.


Kann ich damit Refactoring verwenden?
Lore

1

Versuchen Sie es mit 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

Versuchen Sie es mit cfg4py :

  1. Hierarchichales Design, mehrere Umgebungen unterstützt, also verwechseln Sie niemals die Entwicklereinstellungen mit den Einstellungen des Produktionsstandorts.
  2. Code-Vervollständigung. Cfg4py konvertiert Ihr Yaml in eine Python-Klasse. Anschließend können Sie den Code vervollständigen, während Sie Ihren Code eingeben.
  3. viel mehr..

HAFTUNGSAUSSCHLUSS: Ich bin der Autor dieses Moduls

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.