Сохранить регистр в ConfigParser? - PullRequest
70 голосов
/ 23 октября 2009

Я пытался использовать модуль 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 ]

92 голосов
/ 23 октября 2009

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

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 вместо его вызова; переопределение может быть сделано в подклассе или в экземпляре. При переопределении установите для него функцию (а не результат вызова функции).

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

25 голосов
/ 23 мая 2014

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

config = ConfigParser.RawConfigParser()
config.optionxform = str 
5 голосов
/ 19 августа 2018

Добавить к вашему коду:

config.optionxform = lambda option: option  # preserve case for letters
3 голосов
/ 11 апреля 2014

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

Отредактировано с учетом предложения @ OozeMeister:

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

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

parser = CaseConfigParser()
parser.read(something)

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

2 голосов
/ 23 февраля 2017

Оговорка:

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

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

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

config.optionxform = str

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

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

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

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

Теперь FOO_BAZ сохранит его, и у вас не будет InterpolationMissingOptionError .

...