J'utilise ConfigParser
pour lire la configuration d'exécution d'un script.
Je voudrais avoir la flexibilité de ne pas fournir de nom de section (il existe des scripts assez simples, ils n'ont pas besoin de «section»). ConfigParser
lèvera une NoSectionError
exception et n'acceptera pas le fichier.
Comment puis-je faire en sorte que ConfigParser récupère simplement les (key, value)
tuples d'un fichier de configuration sans nom de section?
Par exemple:
key1=val1
key2:val2
Je préfère ne pas écrire dans le fichier de configuration.
python
parsing
configuration-files
Escualo
la source
la source
Réponses:
Alex Martelli a fourni une solution pour
ConfigParser
analyser des.properties
fichiers (qui sont apparemment des fichiers de configuration sans section).Sa solution est un wrapper de type fichier qui insérera automatiquement un en-tête de section factice pour satisfaire
ConfigParser
les exigences de.la source
Eclairé par cette réponse de jterrace , je propose cette solution:
ini_str = '[root]\n' + open(ini_path, 'r').read() ini_fp = StringIO.StringIO(ini_str) config = ConfigParser.RawConfigParser() config.readfp(ini_fp)
EDIT pour les futurs googleurs: à partir de Python 3.4+, il
readfp
est obsolète etStringIO
n'est plus nécessaire. Au lieu de cela, nous pouvons utiliserread_string
directement:with open('config_file') as f: file_content = '[dummy_section]\n' + f.read() config_parser = ConfigParser.RawConfigParser() config_parser.read_string(file_content)
la source
Vous pouvez le faire en une seule ligne de code.
Dans python 3, ajoutez un faux en-tête de section aux données de votre fichier de configuration et transmettez-le à
read_string()
.from configparser import ConfigParser parser = ConfigParser() with open("foo.conf") as stream: parser.read_string("[top]\n" + stream.read()) # This line does the trick.
Vous pouvez également utiliser
itertools.chain()
pour simuler un en-tête de section pourread_file()
. Cela peut être plus efficace en mémoire que l'approche ci-dessus, ce qui peut être utile si vous avez des fichiers de configuration volumineux dans un environnement d'exécution contraint.from configparser import ConfigParser from itertools import chain parser = ConfigParser() with open("foo.conf") as lines: lines = chain(("[top]",), lines) # This line does the trick. parser.read_file(lines)
Dans python 2, ajoutez un faux en-tête de section aux données de votre fichier de configuration, enveloppez le résultat dans un
StringIO
objet et transmettez-le àreadfp()
.from ConfigParser import ConfigParser from StringIO import StringIO parser = ConfigParser() with open("foo.conf") as stream: stream = StringIO("[top]\n" + stream.read()) # This line does the trick. parser.readfp(stream)
Avec l'une de ces approches, vos paramètres de configuration seront disponibles dans
parser.items('top')
.Vous pouvez également utiliser StringIO dans python 3, peut-être pour la compatibilité avec les anciens et les nouveaux interpréteurs python, mais notez qu'il réside désormais dans le
io
package et qu'ilreadfp()
est désormais obsolète.Vous pouvez également envisager d'utiliser un analyseur TOML au lieu de ConfigParser.
la source
Vous pouvez utiliser la bibliothèque ConfigObj pour le faire simplement: http://www.voidspace.org.uk/python/configobj.html
Mise à jour: trouvez le dernier code ici .
Si vous êtes sous Debian / Ubuntu, vous pouvez installer ce module en utilisant votre gestionnaire de paquets:
Un exemple d'utilisation:
from configobj import ConfigObj config = ConfigObj('myConfigFile.ini') config.get('key1') # You will get val1 config.get('key2') # You will get val2
la source
Le moyen le plus simple de le faire est d'utiliser l'analyseur CSV de python, à mon avis. Voici une fonction de lecture / écriture démontrant cette approche ainsi qu'un pilote de test. Cela devrait fonctionner à condition que les valeurs ne soient pas autorisées à être multilignes. :)
import csv import operator def read_properties(filename): """ Reads a given properties file with each line of the format key=value. Returns a dictionary containing the pairs. Keyword arguments: filename -- the name of the file to be read """ result={ } with open(filename, "rb") as csvfile: reader = csv.reader(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) for row in reader: if len(row) != 2: raise csv.Error("Too many fields on row with contents: "+str(row)) result[row[0]] = row[1] return result def write_properties(filename,dictionary): """ Writes the provided dictionary in key-sorted order to a properties file with each line of the format key=value Keyword arguments: filename -- the name of the file to be written dictionary -- a dictionary containing the key/value pairs. """ with open(filename, "wb") as csvfile: writer = csv.writer(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) for key, value in sorted(dictionary.items(), key=operator.itemgetter(0)): writer.writerow([ key, value]) def main(): data={ "Hello": "5+5=10", "World": "Snausage", "Awesome": "Possum" } filename="test.properties" write_properties(filename,data) newdata=read_properties(filename) print "Read in: " print newdata print contents="" with open(filename, 'rb') as propfile: contents=propfile.read() print "File contents:" print contents print ["Failure!", "Success!"][data == newdata] return if __name__ == '__main__': main()
la source
csv
module pour résoudre desConfigParser
plaintes courantes . Facilement généralisé davantage et conçu pour être à la fois compatible Python 2 et 3 .Ayant moi-même rencontré ce problème, j'ai écrit un wrapper complet à ConfigParser (la version en Python 2) qui peut lire et écrire des fichiers sans sections de manière transparente, basé sur l'approche d'Alex Martelli liée à la réponse acceptée. Il devrait remplacer toute utilisation de ConfigParser. En le publiant au cas où quelqu'un en aurait besoin trouverait cette page.
import ConfigParser import StringIO class SectionlessConfigParser(ConfigParser.RawConfigParser): """ Extends ConfigParser to allow files without sections. This is done by wrapping read files and prepending them with a placeholder section, which defaults to '__config__' """ def __init__(self, *args, **kwargs): default_section = kwargs.pop('default_section', None) ConfigParser.RawConfigParser.__init__(self, *args, **kwargs) self._default_section = None self.set_default_section(default_section or '__config__') def get_default_section(self): return self._default_section def set_default_section(self, section): self.add_section(section) # move all values from the previous default section to the new one try: default_section_items = self.items(self._default_section) self.remove_section(self._default_section) except ConfigParser.NoSectionError: pass else: for (key, value) in default_section_items: self.set(section, key, value) self._default_section = section def read(self, filenames): if isinstance(filenames, basestring): filenames = [filenames] read_ok = [] for filename in filenames: try: with open(filename) as fp: self.readfp(fp) except IOError: continue else: read_ok.append(filename) return read_ok def readfp(self, fp, *args, **kwargs): stream = StringIO() try: stream.name = fp.name except AttributeError: pass stream.write('[' + self._default_section + ']\n') stream.write(fp.read()) stream.seek(0, 0) return ConfigParser.RawConfigParser.readfp(self, stream, *args, **kwargs) def write(self, fp): # Write the items from the default section manually and then remove them # from the data. They'll be re-added later. try: default_section_items = self.items(self._default_section) self.remove_section(self._default_section) for (key, value) in default_section_items: fp.write("{0} = {1}\n".format(key, value)) fp.write("\n") except ConfigParser.NoSectionError: pass ConfigParser.RawConfigParser.write(self, fp) self.add_section(self._default_section) for (key, value) in default_section_items: self.set(self._default_section, key, value)
la source
La réponse de Blueicefield mentionnait configobj, mais la bibliothèque originale ne supporte que Python 2. Elle a maintenant un port compatible Python 3+:
https://github.com/DiffSK/configobj
Les API n'ont pas changé, voir sa doc .
la source