Quelle est la meilleure pratique d'utilisation d'un fichier de paramètres en Python? [fermé]

332

J'ai un script de ligne de commande que j'exécute avec beaucoup d'arguments. J'en suis maintenant arrivé à un point où j'ai trop d'arguments et je veux aussi avoir des arguments sous forme de dictionnaire.

Donc, pour simplifier les choses, je voudrais plutôt exécuter le script avec un fichier de paramètres. Je ne sais pas vraiment quelles bibliothèques utiliser pour l'analyse du fichier. Quelle est la meilleure pratique pour ce faire? Je pourrais bien sûr marteler quelque chose moi-même, mais s'il y a une bibliothèque pour cela, je suis tout à fait à l'écoute.

Quelques «demandes»:

  • Plutôt que d'utiliser, pickleje voudrais que ce soit un fichier texte simple qui puisse être facilement lu et édité.
  • Je veux pouvoir y ajouter des données de type dictionnaire, c'est-à-dire qu'une certaine forme d'imbrication devrait être prise en charge.

Un pseudo exemple de fichier simplifié:

truck:
    color: blue
    brand: ford
city: new york
cabriolet:
    color: black
    engine:
        cylinders: 8
        placement: mid
    doors: 2
c00kiemonster
la source
6
La syntaxe particulière de cet exemple de fichier est en fait YAML, vérifiez la réponse de Benson.
Skippy le Grand Gourou du

Réponses:

231

Vous pouvez avoir un module Python standard, par exemple config.py, comme ceci:

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

et utilisez-le comme ceci:

import config
print config.truck['color']  
dugres
la source
69
C'est une assez mauvaise idée, car si vous voulez autoriser les utilisateurs à faibles privilèges à modifier uniquement les fichiers de configuration, vous leur permettez essentiellement de se faufiler dans du code privilégié.
nikolay
172
Permettre aux utilisateurs "à faibles privilèges" de changer la configuration d'un programme plus privilégié est probablement une configuration discutable de toute façon.
XTL
18
Vous pouvez également rencontrer des problèmes pour empaqueter votre projet pour le déploiement à l'aide d'un outil tel que py2app. L'utilisateur peut ne pas être en mesure de modifier le fichier de configuration une fois qu'il est distribué car cela invaliderait la signature de l'application.
bschwagg
18
Le principal inconvénient de cette option (sinon très pratique) est que les .pyfichiers sont exécutables, donc tout type de code peut être exécuté tout en essayant de charger la configuration import. C'est inacceptable du point de vue de la sécurité.
Apalala
5
Une version de ceci ne peut-elle pas être effectuée en toute sécurité ast.literal_eval? docs.python.org/3/library/ast.html#ast.literal_eval
André C. Andersen
169

L'exemple de configuration que vous avez fourni est en fait YAML valide . En fait, YAML répond à toutes vos demandes, est implémenté dans un grand nombre de langues et est extrêmement convivial. Je vous recommande fortement de l'utiliser. Le projet PyYAML fournit un joli module python, qui implémente YAML.

Utiliser le module yaml est extrêmement simple:

import yaml
config = yaml.safe_load(open("path/to/config.yml"))
Benson
la source
3
yaml est toujours quelque chose vers lequel je me tourne; le format peut aller du simple simple au support du code python intégré, et la bibliothèque standard fait le gros du travail d'analyse et d'assainissement pour vous.
Todor Minakov
15
D'accord. Pour vous ou les utilisateurs qui écrivent YAML, voici la meilleure référence YAML que je connaisse . La documentation officielle est malheureusement une spécification destinée aux implémenteurs, et rien d'autre, mais le guide d'Eevee est fantastique.
Esteis
5
Pour nous non initiés, c'est pip3 install pyyamlpour le préparer à l'importer dans des scripts python.
user8675309
2
Attention, yaml n'est convivial que si vous restez très simple, il a par défaut des tonnes de problématiques, à la limite de fonctionnalités dangereuses. Essayez plutôt hitchdev.com/strictyaml comme alternative lite sûre par défaut.
Gringo Suave
107

J'ai trouvé cela le plus utile et le plus facile à utiliser https://wiki.python.org/moin/ConfigParserExamples

Vous venez de créer un "myfile.ini" comme:

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

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

[Others]
Route: 66

Et récupérez les données comme:

>>> 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
la source
20
Pour Python 3, utilisez plutôt le module configparser (tout en minuscules)
Roland
2
C'est la solution la plus rapide, la plus claire et la plus facile à implémenter, car il n'y a pas d'implémentation, juste une utilisation. :) Je vous remercie!
Aleksandar du
Est-ce que cela prendrait en charge les dictionnaires imbriqués comme demandé dans la question?
Jakub Bláha
54

Yaml et Json sont les formats de fichiers les plus simples et les plus couramment utilisés pour stocker les paramètres / configuration. PyYaml peut être utilisé pour analyser le yaml. Json fait déjà partie de python à partir de la 2.5. Yaml est un sur-ensemble de Json. Json résoudra la plupart des cas d'utilisation, sauf les chaînes multi-lignes où l'échappement est requis. Yaml s'occupe également de ces cas.

>>> 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
la source
13
Bien que plus ou moins équivalent, json n'est pas aussi lisible par l'homme que yaml. Étant donné que sa configuration d'échantillon est en fait yaml valide, je soulignerais cela au lieu de json.
Benson
23
L'utilisation de "json.dump (config, fp, sort_keys = True, indent = 4)" améliore la lisibilité.
phobie