Was ist die beste Vorgehensweise bei der Verwendung einer Einstellungsdatei in Python? [geschlossen]

332

Ich habe ein Befehlszeilenskript, das ich mit vielen Argumenten ausführe. Ich bin jetzt an einem Punkt angelangt, an dem ich zu viele Argumente habe, und ich möchte auch einige Argumente in Wörterbuchform haben.

Um die Dinge zu vereinfachen, möchte ich das Skript stattdessen mit einer Einstellungsdatei ausführen. Ich weiß nicht genau, welche Bibliotheken zum Parsen der Datei verwendet werden sollen. Was ist die beste Vorgehensweise dafür? Ich könnte natürlich selbst etwas herausschlagen, aber wenn es eine Bibliothek dafür gibt, bin ich ganz Ohr.

Ein paar "Forderungen":

  • Anstatt zu verwenden, picklemöchte ich, dass es sich um eine einfache Textdatei handelt, die leicht gelesen und bearbeitet werden kann.
  • Ich möchte in der Lage sein, wörterbuchähnliche Daten hinzuzufügen, dh eine Form der Verschachtelung sollte unterstützt werden.

Eine vereinfachte Pseudo-Beispieldatei:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2
c00kiemonster
quelle
6
Die spezielle Syntax dieser Beispieldatei lautet tatsächlich YAML. Überprüfen Sie die Antwort von Benson.
Skippy le Grand Gourou

Antworten:

230

Sie können ein reguläres Python-Modul haben, z. B. config.py, wie folgt:

truck = dict(
    color = 'blue',
    brand = 'ford',
)
city = 'new york'
cabriolet = dict(
    color = 'black',
    engine = dict(
        cylinders = 8,
        placement = 'mid',
    ),
    doors = 2,
)

und benutze es so:

import config
print config.truck['color']  
Dugres
quelle
68
Dies ist eine ziemlich schlechte Idee, als ob Sie Benutzern mit geringen Berechtigungen erlauben möchten, nur Konfigurationsdateien zu ändern. Auf diese Weise erlauben Sie ihnen im Wesentlichen, sich in privilegierten Code einzuschleichen.
Nikolay
171
Das Zulassen, dass Benutzer mit "niedrigen Berechtigungen" die Konfiguration für ein privilegierteres Programm ändern, ist wahrscheinlich ohnehin eine fragwürdige Einrichtung.
XTL
18
Möglicherweise treten auch Probleme beim Packen Ihres Projekts für die Bereitstellung mit einem Tool wie py2app auf. Der Benutzer kann die Konfigurationsdatei möglicherweise nicht mehr bearbeiten, sobald sie verteilt wurde, da dies die Signatur der App ungültig machen würde.
bschwagg
18
Der Hauptnachteil bei dieser (ansonsten sehr praktischen) Option besteht darin, dass .pyDateien ausführbar sind, sodass beim Laden der Konfiguration jede Art von Code ausgeführt werden kann import. Das ist aus Sicherheitsgründen nicht akzeptabel.
Apalala
5
Kann eine Version davon nicht sicher gemacht werden ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
André C. Andersen
168

Die von Ihnen angegebene Beispielkonfiguration ist tatsächlich eine gültige YAML . Tatsächlich erfüllt YAML alle Ihre Anforderungen, ist in einer Vielzahl von Sprachen implementiert und äußerst menschenfreundlich. Ich würde Ihnen wärmstens empfehlen, es zu verwenden. Das PyYAML-Projekt bietet ein schönes Python-Modul, das YAML implementiert.

Die Verwendung des Yaml-Moduls ist äußerst einfach:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))
Benson
quelle
3
Yaml ist immer etwas, an das ich mich wende; Das Format kann von kinderleicht bis zur Unterstützung von eingebettetem Python-Code reichen, und die Standardbibliothek erledigt das schwere Parsen und Bereinigen für Sie.
Todor Minakov
14
Einverstanden. Für Sie oder Benutzer, die YAML schreiben, ist hier die beste YAML-Referenz, die ich kenne . Die offizielle Dokumentation richtet sich leider an Implementierer und nichts anderes, aber Eevees Leitfaden ist fantastisch.
Esteis
5
Für uns Uneingeweihte bedeutet dies, pip3 install pyyamles für den Import in Python-Skripte vorzubereiten.
user8675309
2
Achtung, Yaml ist nur dann freundlich, wenn Sie es sehr einfach halten. Standardmäßig gibt es jede Menge Probleme, die an unsichere Funktionen grenzen. Versuchen Sie stattdessen hitchdev.com/strictyaml als standardmäßige Lite-Alternative.
Gringo Suave
107

Ich fand dies am nützlichsten und am einfachsten zu verwendenden https://wiki.python.org/moin/ConfigParserExamples

Sie erstellen einfach eine "myfile.ini" wie:

[SectionOne]
Status: Single
Name: Derek
Value: Yes
Age: 30
Single: True

[SectionTwo]
FavoriteColor=Green
[SectionThree]
FamilyName: Johnson

[Others]
Route: 66

Und rufen Sie die Daten ab wie:

>>> import ConfigParser
>>> Config = ConfigParser.ConfigParser()
>>> Config
<ConfigParser.ConfigParser instance at 0x00BA9B20>
>>> Config.read("myfile.ini")
['c:\\tomorrow.ini']
>>> Config.sections()
['Others', 'SectionThree', 'SectionOne', 'SectionTwo']
>>> Config.options('SectionOne')
['Status', 'Name', 'Value', 'Age', 'Single']
>>> Config.get('SectionOne', 'Status')
'Single'
Maviles
quelle
20
Verwenden Sie für Python 3 stattdessen das configparser- Modul (alle Kleinbuchstaben)
Roland
2
Dies ist die schnellste, klarste und am einfachsten zu implementierende Lösung, da es keine Implementierung gibt, sondern nur die Verwendung. :) Danke!
Aleksandar
Würde dies verschachtelte Wörterbücher unterstützen, wie in der Frage gestellt?
Jakub Bláha
54

Yaml und Json sind die einfachsten und am häufigsten verwendeten Dateiformate zum Speichern von Einstellungen / Konfigurationen. PyYaml kann zum Parsen von Yaml verwendet werden. Json ist bereits ab 2.5 Teil von Python. Yaml ist eine Obermenge von Json. Json löst die meisten Anwendungsfälle mit Ausnahme von mehrzeiligen Zeichenfolgen, bei denen ein Escapezeichen erforderlich ist. Yaml kümmert sich auch um diese Fälle.

>>> import json
>>> config = {'handler' : 'adminhandler.py', 'timeoutsec' : 5 }
>>> json.dump(config, open('/tmp/config.json', 'w'))
>>> json.load(open('/tmp/config.json'))   
{u'handler': u'adminhandler.py', u'timeoutsec': 5}
Anoop
quelle
13
Json ist zwar mehr oder weniger gleichwertig, aber bei weitem nicht so gut lesbar wie Yaml. Da seine Beispielkonfiguration tatsächlich gültiges yaml ist, würde ich das anstelle von json betonen.
Benson
23
Die Verwendung von "json.dump (config, fp, sort_keys = True, indent = 4)" verbessert die Lesbarkeit.
Phobie