python - configuracion - como instalar configparser
Usar el ConfigParser de Python para leer un archivo sin nombre de sección (8)
Estoy usando ConfigParser para leer la configuración de tiempo de ejecución de un script.
Me gustaría tener la flexibilidad de no proporcionar un nombre de sección (hay scripts que son lo suficientemente simples, no necesitan una ''sección''). ConfigParser lanzará la excepción NoSectionError
y no aceptará el archivo.
¿Cómo puedo hacer que ConfigParser simplemente recupere las tuplas (key, value)
de un archivo de configuración sin nombres de sección? Por ejemplo:
key1=val1
key2:val2
Preferiría no escribir en el archivo de configuración.
Alex Martelli brindó una solución para usar ConfigParser
para analizar archivos .properties
(que aparentemente son archivos de configuración sin sección).
Su solución es un contenedor similar a un archivo que automáticamente insertará un encabezado de sección ficticia para satisfacer los requisitos de ConfigParser
.
Habiendo encontrado este problema yo mismo, escribí un contenedor completo para ConfigParser (la versión en Python 2) que puede leer y escribir archivos sin secciones de manera transparente, basado en el enfoque de Alex Martelli vinculado en la respuesta aceptada. Debe ser un reemplazo directo a cualquier uso de ConfigParser. Publicarlo en caso de que alguien que lo necesite encuentre esta página.
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)
Iluminado por esta respuesta por jterrace , se me ocurrió esta solución:
- Leer todo el archivo en una cadena
- Prefijo con un nombre de sección predeterminado
- Use StringIO para imitar un objeto similar a un archivo
ini_str = ''[root]/n'' + open(ini_path, ''r'').read()
ini_fp = StringIO.StringIO(ini_str)
config = ConfigParser.RawConfigParser()
config.readfp(ini_fp)
EDITAR para futuros usuarios de Google: a partir de Python 3.4+ readfp
está en desuso, y StringIO
ya no es necesario. En cambio, podemos usar read_string
directamente:
with open(''config_file'') as f:
file_content = ''[dummy_section]/n'' + f.read()
config_parser = RawConfigParser()
config_parser.read_string(file_content)
La forma más fácil de hacerlo es usar el analizador de CSV de Python, en mi opinión. Aquí hay una función de lectura / escritura que demuestra este enfoque, así como un controlador de prueba. Esto debería funcionar siempre que los valores no sean multilíneas. :)
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 respuesta de Blueicefield menciona configobj, pero la lib original solo admite Python 2. Ahora tiene un puerto compatible con Python 3+:
https://github.com/DiffSK/configobj
Las API no han cambiado, mira que es un doc .
Puede usar la biblioteca ConfigObj para hacer eso simplemente: http://www.voidspace.org.uk/python/configobj.html
Actualizado: Encuentre el último código here .
Si está en Debian / Ubuntu, puede instalar este módulo usando su administrador de paquetes:
apt-get install python-configobj
Un ejemplo de uso:
from configobj import ConfigObj
config = ConfigObj(''myConfigFile.ini'')
config.get(''key1'') # You will get val1
config.get(''key2'') # You will get val2
Puedes hacer esto con una sola línea de código adicional. (Dos líneas si cuenta import
estados de import
).
En python 3, use itertools.chain()
para simular un encabezado de sección para read_file()
.
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)
En python 2, añada una línea de encabezado de sección a los datos que lee de su archivo de configuración, StringIO
el resultado en un objeto StringIO
y páselo a 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)
Con cualquiera de los enfoques, su configuración de configuración estará disponible en parser.items(''top'')
.
También podría usar StringIO
en python 3, importándolo de su nuevo hogar en el paquete io
, pero tenga en cuenta que readfp()
está en desuso en python 3 y, por lo tanto, debe evitarse.
Si no te importa una dependencia adicional, podrías considerar usar un analizador TOML lugar de ConfigParser.
configobj lib puede ayudar en caso de que KEY="value"
from configobj import ConfigObj
cfg = ConfigObj(''/home/.aws/config'')
access_key_id = cfg[''aws_access_key_id'']
secret_access_key = cfg[''aws_secret_access_key'']