write parser files cfg python key-value ini

parser - load json config python



analizando el archivo.properties en Python (9)

¡HURRA! otra version

Basado en esta respuesta (la adición usa un dict , with declaración y admite el carácter % )

import ConfigParser import StringIO import os def read_properties_file(file_path): with open(file_path) as f: config = StringIO.StringIO() config.write(''[dummy_section]/n'') config.write(f.read().replace(''%'', ''%%'')) config.seek(0, os.SEEK_SET) cp = ConfigParser.SafeConfigParser() cp.readfp(config) return dict(cp.items(''dummy_section''))

Uso

props = read_properties_file(''/tmp/database.properties'') # It will raise if `name` is not in the properties file name = props[''name''] # And if you deal with optional settings, use: connection_string = props.get(''connection-string'') password = props.get(''password'') print name, connection_string, password

el archivo .properties utilizado en mi ejemplo

name=mongo connection-string=mongodb://... password=my-password%1234

Editar 2015-11-06

Gracias a Neill Lima por mencionar que hubo un problema con el carácter % .

El motivo de ello es que ConfigParser está diseñado para analizar archivos .ini . El carácter % es una sintaxis especial. para usar el carácter % simplemente agregue aa reemplazar por % con %% acuerdo con la sintaxis .ini .

El módulo ConfigParser genera una excepción si uno analiza un archivo .properties estilo Java simple, cuyo contenido son pares clave-valor (es decir, sin encabezados de sección de estilo INI). ¿Hay alguna solución?


Digamos que tienes, por ejemplo:

$ cat my.props first: primo second: secondo third: terzo

es decir, sería un formato .config , excepto que falta un nombre de sección .config . Entonces, es fácil falsificar el encabezado de la sección:

import ConfigParser class FakeSecHead(object): def __init__(self, fp): self.fp = fp self.sechead = ''[asection]/n'' def readline(self): if self.sechead: try: return self.sechead finally: self.sechead = None else: return self.fp.readline()

uso:

cp = ConfigParser.SafeConfigParser() cp.readfp(FakeSecHead(open(''my.props''))) print cp.items(''asection'')

salida:

[(''second'', ''secondo''), (''third'', ''terzo''), (''first'', ''primo'')]


La respuesta anterior de Alex Martelli no funciona para Python 3.2+: readfp() ha sido reemplazado por read_file() , y ahora toma un iterador en lugar de usar el método readline() .

Aquí hay un fragmento de código que utiliza el mismo enfoque, pero funciona en Python 3.2+.

>>> import configparser >>> def add_section_header(properties_file, header_name): ... # configparser.ConfigParser requires at least one section header in a properties file. ... # Our properties file doesn''t have one, so add a header to it on the fly. ... yield ''[{}]/n''.format(header_name) ... for line in properties_file: ... yield line ... >>> file = open(''my.props'', encoding="utf_8") >>> config = configparser.ConfigParser() >>> config.read_file(add_section_header(file, ''asection''), source=''my.props'') >>> config[''asection''][''first''] ''primo'' >>> dict(config[''asection'']) {''second'': ''secondo'', ''third'': ''terzo'', ''first'': ''primo''} >>>


Mi solución es usar StringIO y StringIO un simple encabezado ficticio:

import StringIO import os config = StringIO.StringIO() config.write(''[dummysection]/n'') config.write(open(''myrealconfig.ini'').read()) config.seek(0, os.SEEK_SET) import ConfigParser cp = ConfigParser.ConfigParser() cp.readfp(config) somevalue = cp.getint(''dummysection'', ''somevalue'')


Otra respuesta para python2.7 basada en la respuesta de Alex Martelli.

import ConfigParser class PropertiesParser(object): """Parse a java like properties file Parser wrapping around ConfigParser allowing reading of java like properties file. Based on example: https://.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788 Example usage ------------- >>> pp = PropertiesParser() >>> props = pp.parse(''/home/kola/configfiles/dev/application.properties'') >>> print props """ def __init__(self): self.secheadname = ''fakeSectionHead'' self.sechead = ''['' + self.secheadname + '']/n'' def readline(self): if self.sechead: try: return self.sechead finally: self.sechead = None else: return self.fp.readline() def parse(self, filepath): self.fp = open(filepath) cp = ConfigParser.SafeConfigParser() cp.readfp(self) self.fp.close() return cp.items(self.secheadname)


Pensé que el comentario "read_string" de MestreLion era agradable y simple y merecía un ejemplo.

Para Python 3.2+, puedes implementar la idea de la "sección ficticia" como esta:

with open(CONFIG_PATH, ''r'') as f: config_string = ''[dummy_section]/n'' + f.read() config = configparser.ConfigParser() config.read_string(config_string)


Esta respuesta sugiere usar itertools.chain en Python 3.

from configparser import ConfigParser from itertools import chain parser = ConfigParser() with open("foo.conf") as lines: lines = chain(("[dummysection]",), lines) # This line does the trick. parser.read_file(lines)


with open(''mykeyvaluepairs.properties'') as f: defaults = dict([line.split() for line in f]) config = configparser.ConfigParser(defaults) config.add_section(''dummy_section'')

Ahora config.get(''dummy_section'', option) devolverá ''option'' de la sección DEFAULT.

o:

with open(''mykeyvaluepairs.properties'') as f: properties = dict([line.split() for line in f]) config = configparser.ConfigParser() config.add_section(''properties'') for prop, val in properties.items(): config.set(''properties'', prop, val)

En cuyo caso config.get(''properties'', option) no recurre a la sección predeterminada.