2011-06-29 2 views

ответ

12

Конфигуратор Python может загружать несколько файлов. Файлы, прочитанные позже, могут переопределить настройки из первого файла.

Например, мое приложение имеет настройки базы данных в своей внутренней по умолчанию файл конфигурации:

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

Я переопределять их на другом сервере с «environment.ini» файл, содержащий тот же раздел, но разные значения :

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

В 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

Благодарим за информацию. К сожалению, это не сработает для меня из-за бизнес-требований наличия одного главного файла, который будет анализироваться на нескольких языках программирования. Похоже, мне нужно реализовать себя. – Maascamp

+0

Maascamp: вам это удалось? У меня такая же ситуация ... – xvga

+2

Да, я реализовал ту, которая соответствовала моим требованиям (стиль Zend_Config_Ini) и, когда это возможно, конвертирует в родные типы python. См. Здесь [https://bitbucket.org/maascamp/pyconfigini](https://bitbucket.org/maascamp/pyconfigini). Надеюсь, поможет. – Maascamp

0

Я также не нашел готового решения. Чтобы решить эту проблему, я приспособил функцию ПОЛУЧИТЬ из ConfigParser искать в разделе ребенка, а затем в родительском разделе:

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 

Ограничения:

  • только-только доступ на чтение к CONFIG поддерживается
  • только один уровень наследования
1

Вот что я использовал. extended_get метод - то, что вам нужно - он поддерживает иерархические разделы.

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

спасибо Roman! Как-то старое имя метода прокралось в код :) – xvga

Смежные вопросы