Сохранить регистр в ConfigParser?


Я пытался использовать в Python ConfigParser модуль для сохранения настроек. Для моего приложения важно, чтобы я сохранил регистр каждого имени в моих разделах. В документах упоминается, что передача str () в ConfigParser.optionxform () сделал бы это, но это не работает для меня. Имена в нижнем регистре. Я что-то упустил?

<~/.myrc contents>
[rules]
Monkey = foo
Ferret = baz

Python псевдокод того, что я получаю:

import ConfigParser,os

def get_config():
   config = ConfigParser.ConfigParser()
   config.optionxform(str())
    try:
        config.read(os.path.expanduser('~/.myrc'))
        return config
    except Exception, e:
        log.error(e)

c = get_config()  
print c.options('rules')
[('monkey', 'foo'), ('ferret', 'baz')]
5 60

5 ответов:

документация сбивает с толку. Они имеют в виду следующее:

import ConfigParser, os
def get_config():
    config = ConfigParser.ConfigParser()
    config.optionxform=str
    try:
        config.read(os.path.expanduser('~/.myrc'))
        return config
    except Exception, e:
        log.error(e)

c = get_config()  
print c.options('rules')

т. е. переопределить optionxform, вместо вызова его; переопределение может быть сделано в подклассе или в экземпляре. При переопределении установите его в функцию (а не в результат вызова функции).

теперь я сообщил это как ошибка, и с тех пор он был исправлен.

для меня работал установить optionxform сразу после создания объекта

config = ConfigParser.RawConfigParser()
config.optionxform = str 

Я знаю ответ на этот вопрос, но я думал, что некоторые люди могут найти это решение полезно. Это класс, который может легко заменить существующий класс ConfigParser.

отредактировано, чтобы включить предложение @OozeMeister:

class CaseConfigParser(ConfigParser):
    def optionxform(self, optionstr):
        return optionstr

использование такое же, как обычный ConfigParser.

parser = CaseConfigParser()
parser.read(something)

Это так, чтобы вам не приходилось устанавливать optionxform каждый раз, когда вы делаете новый ConfigParser, что довольно утомительно.

предостережение:

если вы используете значения по умолчанию с ConfigParser, т. е.:

config = ConfigParser.SafeConfigParser({'FOO_BAZ': 'bar'})

а затем попробуйте сделать парсер чувствительным к регистру с помощью этого:

config.optionxform = str

все ваши параметры из файла (ов) конфигурации сохранят свой случай, но FOO_BAZ будет преобразован в нижний регистр.

чтобы значения по умолчанию также сохраняли свой случай, используйте подклассы, как в @icedtrees ответ:

class CaseConfigParser(ConfigParser.SafeConfigParser):
    def optionxform(self, optionstr):
        return optionstr

config = CaseConfigParser({'FOO_BAZ': 'bar'})

теперь FOO_BAZ будет держать это дело и у вас не будет InterpolationMissingOptionError.

добавить в код:

config.optionxform = lambda option: option  # preserve case for letters