2010-07-10 7 views
17

Normalmente, código como sigue, para conseguir un elemento particular en una variable de la siguienteLeer todos los contenidos en el archivo INI en el diccionario con Python

try: 
    config = ConfigParser.ConfigParser() 
    config.read(self.iniPathName) 
except ConfigParser.MissingSectionHeaderError, e: 
    raise WrongIniFormatError(`e`) 

try: 
    self.makeDB = config.get("DB","makeDB") 
except ConfigParser.NoOptionError: 
    self.makeDB = 0 

¿Hay alguna manera de leer todo el contenido de un diccionario de Python ?

Por ejemplo

 
[A] 
x=1 
y=2 
z=3 
[B] 
x=1 
y=2 
z=3 

se escribe en

 
val["A"]["x"] = 1 
... 
val["B"]["z"] = 3 

Respuesta

26

Sugiero subclases ConfigParser.ConfigParser (o SafeConfigParser, & c) para acceder de forma segura el "protegido" atributos (nombres que comienzan con un solo subrayado - "privado" habría nombres que comienzan con dos guiones bajos, no para ser visitada incluso en subclases ...):

import ConfigParser 

class MyParser(ConfigParser.ConfigParser): 

    def as_dict(self): 
     d = dict(self._sections) 
     for k in d: 
      d[k] = dict(self._defaults, **d[k]) 
      d[k].pop('__name__', None) 
     return d 

Esto emula la lógica habitual de programas de análisis de configuración, y está garantizado para trabajar en todas las versiones de Python donde hay un módulo ConfigParser.py (hasta 2,7, que es el último de la serie 2.* - sabiendo que no habrá futuro Python 2.any versiones es cómo compati La capacidad puede ser garantizada ;-).

Si necesita apoyar futuras versiones de Python 3.* (hasta 3.1 y probablemente el más pronto próxima 3.2 que debería estar bien, simplemente cambiando el nombre del módulo para todo minúsculas configparser lugar, por supuesto) que puede necesitar un poco de atención/Ajustes unos pocos años después, pero no esperaría nada importante.

23

logré obtener una respuesta, pero espero que no debe haber una mejor.

dictionary = {} 
for section in config.sections(): 
    dictionary[section] = {} 
    for option in config.options(section): 
     dictionary[section][option] = config.get(section, option) 
+2

Creo que esta es una solución muy buena, por qué no estás contento con él? –

+2

Esta debería ser la respuesta porque resuelve el problema sin tener que usar el atributo "_secciones" "privado". Y, por supuesto, si uno necesita usar un OrderedDict, simplemente use eso en lugar del dict regular. – SizzlingVortex

+1

Reemplazando 'dictionary' con un' defaultdict (dict) 'eliminaría la creación del dict intermedio. – noxdafox

10

Los datos de instancia para ConfigParser se almacenan internamente como dict anidados. En lugar de volver a crearlo, puedes copiarlo.

>>> import ConfigParser 
>>> p = ConfigParser.ConfigParser() 
>>> p.read("sample_config.ini") 
['sample_config.ini'] 
>>> p.__dict__ 
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B':   {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>} 
>>> d = p.__dict__['_sections'].copy() 
>>> d 
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}} 

Edita:

Alex Martelli solution es más limpio, más robusto, y más bonita. Si bien esta fue la respuesta aceptada, sugeriría utilizar su enfoque en su lugar. Vea su comentario a esta solución para más información.

+4

Siempre soy reacio a acceder a nombres de atributos protegidos ("start-with-underscore") (y la absurda complicación de pasar por '__dict__' no ayuda para nada -' d = p._sections.copy() 'es exactamente equivalente, más simple y más directo). Es por eso que sugerí en mi respuesta la alternativa de usar una subclase en su lugar: se espera que las subclases accedan a los atributos protegidos de la clase base. En C++ esto se aplica; en Python, no lo es, pero eso se debe a que se supone que los usuarios deben ser lo suficientemente disciplinados como para no necesitar una aplicación ;-). –

1

Cómo analizar el archivo ini en py?

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read('/var/tmp/test.ini') 
print config.get('DEFAULT', 'network') 

Dónde archivo Prueba.ini contiene:

[DEFAULT] 
network=shutup 
others=talk 
6

Sé que esta pregunta se hizo hace 5 años, pero hoy he hecho esta comprensión dict cosita:

parser = ConfigParser() 
parser.read(filename) 
confdict = {section: dict(parser.items(section)) for section in parser.sections()} 
0

Una cosa más a tener en cuenta es que ConfigParser convierte los valores de clave a minúsculas, por lo tanto, en caso de que esté convirtiendo las entradas de configuración en un diccionario, verifique sus requisitos. Enfrenté un problema debido a esto. En mi caso, tenía claves camel case, tuve que cambiar cierta cantidad de código cuando comencé a usar el diccionario en lugar de archivos.El método ConfigParser.get() convierte internamente la clave en minúsculas.

-1

de https://wiki.python.org/moin/ConfigParserExamples

def ConfigSectionMap(section): 
dict1 = {} 
options = Config.options(section) 
for option in options: 
    try: 
     dict1[option] = Config.get(section, option) 
     if dict1[option] == -1: 
      DebugPrint("skip: %s" % option) 
    except: 
     print("exception on %s!" % option) 
     dict1[option] = None 
return dict1 
Cuestiones relacionadas