2011-06-29 7 views

Respuesta

12

Python's ConfigParser puede cargar varios archivos. Los archivos leídos más tarde pueden anular la configuración del primer archivo.

Por ejemplo, mi aplicación tiene ajustes de base de datos en su interior por defecto fichero de configuración:

[database] 
server = 127.0.0.1 
port = 1234 
... 

que anulan estos en un servidor diferente con un archivo "environment.ini" que contiene la misma sección, pero diferentes valores :

[database] 
server = 192.168.0.12 
port = 2345 
... 

En Python:

import os 
from ConfigParser import ConfigParser 
dbconf = ConfigParser() 
dbconf.readfp(open('default.ini')) 
if os.path.exists('environment.ini'): 
    dbconf.readfp(open('environment.ini')) 
dbconf.get('database', 'server') # Returns 192.168.0.12 
+1

Gracias por la información. Lamentablemente, esto no funcionará para mí debido a un requisito empresarial de tener un archivo maestro que se analizará en varios lenguajes de programación. Parece que tendré que implementarme. – Maascamp

+0

Maascamp: ¿tuviste éxito? Tengo la misma situación ... – xvga

+2

Sí, implementé uno que cumplía con mis requisitos (estilo Zend_Config_Ini) y se convierte a tipos nativos de python cuando es posible. Vea aquí [https://bitbucket.org/maascamp/pyconfigini](https://bitbucket.org/maascamp/pyconfigini). Espero eso ayude. – Maascamp

0

Tampoco encontré ninguna solución preparada. Para resolverlo, me he adaptado la función get de ConfigParser para buscar en la sección infantil y después en la sección de los padres:

config = SafeConfigParser() 
config.read(filenames) 
required_environment = "mysection" 

# determine fallback requirement in case parameter is not found in required environment 
fallback_environment = "default" 
# loop through all sections of config files 
for environment in config.sections(): 
    # check whether we find an inheritance based on the required section 
    if re.search(required_environment + " *: *\w+", environment): 
     # found inheritance, take parent as fallback section 
     fallback_environment = re.sub(required_environment + r" : (\w+)", r"\1", environment) 
     # take this name as requested section 
     required_environment = environment 

# override get method 
_config_parser_get = config.get 
def myConfigParserGet(id): 
    # check different sections for desired value 
    if config.has_option(required_environment, id): 
     return _config_parser_get(required_environment, id) 
    else: 
     return _config_parser_get(fallback_environment, id) 

config.get = myConfigParserGet 

Restricciones:

  • únicamente acceso de sólo lectura a config apoyado
  • solo un nivel de herencia
1

Esto es lo que he usado. El método extended_get es lo que necesita: admite secciones jerárquicas.

import re 
import io 
import ConfigParser 

class ZendConfigParser(ConfigParser.ConfigParser): 
    def extended_get(self, section, key): 
     if self.has_option(section, key): 
      return self.get(section, key) 
     else: 
      orig_section, parent_section = self._get_orig_section(section) 
      if orig_section != None: 
       if self.has_option(orig_section,key): 
        return self.get(orig_section,key) 
       else: 
        return self.extended_get(parent_section,key) 
      else: 
       return None 



    def _get_orig_section(self, zend_section): 
     orig_section = None 
     parent_section = None 
     for section in self.sections(): 
      if re.search(r'^[ \t]*' + zend_section + '\\b', section) != None: 
       orig_section = section 
       #look for a parent section 
       match = re.match(r'\w+[ \t]*:[ \t]*(\w+)$', section) 
       if match != None: 
        parent_section = match.groups()[0] 
       break 

     return (orig_section, parent_section) 

config = ZendConfigParser() 
config.read(file) 
print(config.extended_get('production', 'database.params.host')) 
+0

gracias Roman! De alguna manera, el nombre del método anterior se coló en el código :) – xvga

Cuestiones relacionadas