【问题标题】:Python config parser that supports section inheritance?支持部分继承的 Python 配置解析器?
【发布时间】:2011-09-25 13:38:27
【问题描述】:

我正在寻找一种 Python 中的 ini 样式配置解析器,它支持类似于 PHP 中的 Zend_Config_Ini 所做的部分继承。

这样的模块是否存在或者我需要自己推出?

【问题讨论】:

    标签: python config ini


    【解决方案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'))
    

    【讨论】:

    • 感谢罗曼!不知何故,旧方法名称潜入了代码:)
    【解决方案2】:

    我也没有找到任何现成的解决方案。为了解决这个问题,我调整了 ConfigParser 的 get 函数在子部分中搜索,然后在父部分中搜索:

    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
    

    限制:

    • 仅支持对配置的只读访问权限
    • 只有一层继承

    【讨论】:

      【解决方案3】:

      Python 的 ConfigParser 可以加载多个文件。稍后读取的文件可以 覆盖第一个文件中的设置。

      例如,我的应用程序在其内部默认值中有数据库设置 配置文件:

      [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
      

      【讨论】:

      • 感谢您的信息。不幸的是,这对我不起作用,因为业务需要拥有一个可以用多种编程语言解析的主文件。看起来我需要自己实现。
      • 是的,我实现了一个满足我的要求(Zend_Config_Ini 风格)并在可能的情况下转换为 python 本机类型。见这里https://bitbucket.org/maascamp/pyconfigini。希望对您有所帮助。
      • @Maascamp 干得好!我正在寻找一个 python ini 解析,例如 Zend_Config_Ini,你应该回答你自己的问题并发布你的解决方案:)
      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      相关资源
      最近更新 更多