Зберегти регістр у ConfigParser?


90

Я намагався використовувати модуль ConfigParser Python для збереження налаштувань. Для мого додатка важливо, щоб я зберігав регістр кожного імені у своїх розділах. У документах згадується, що передача 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')]

Відповіді:


114

Документація заплутана. Що вони означають це:

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

Зараз я повідомив про це як про помилку , і з тих пір це було виправлено.


Дякую. Це працює, і я погоджуюсь, що документи заплутані.
pojo

39

Для мене працював над тим, щоб встановити optionxform відразу після створення об'єкта

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

2
Чудово працює! (зауважте, що в python 3 це назва класу "configparser" (без великих літер)
Ноам Манос

1
@NoamManos: Ви маєте на увазі ім'я модуля (ім'я класу все ще є ConfigParser ).
Йонас Бистрем

2
Зверніть увагу, що це теж працює зConfigParser.ConfigParser()
Jean-Francois T.

Справді. Це працює. Варто згадати, що цей параметр по суті не пов’язаний з RawConfigParser (), оскільки він також підтримує клас ConfigParser (). Спасибі людино.
ivanleoncz

7

Додайте до свого коду:

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

1
Здається, це працює для мене принаймні в python 2.7 і набагато чіткіше прийнятої відповіді. Дякую Фу!
hrbdg,

2
це те саме, що config.optionxform=strнайкраща оцінка відповіді - див. рядок :) просто замість вашої lamdba @Martin v. Löwis використовує вбудовану strфункцію
xuthus

@xuthus - Дійсно, ви можете використовувати 11 рядків коду замість 1 рядка. Як тобі до вподоби.
FooBar167

4

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

Відредаговано для включення пропозиції @ OozeMeister:

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

Використання те саме, що і звичайний ConfigParser.

parser = CaseConfigParser()
parser.read(something)

Це так, щоб вам не довелося встановлювати optionxform кожного разу, коли ви робите нову ConfigParser, що є якось нудно.


Оскільки optionxformце лише метод RawConfigParser, якщо ви збираєтеся йти до створення власного підкласу, вам слід замість цього просто перевизначити метод для підкласу, а не перевизначати його за екземпляром:class CaseConfigParser(ConfigParser): def optionxform(self, optionstr): return optionstr
OozeMeister

@OozeMeister чудова ідея!
icedtrees

2

Застереження:

Якщо ви використовуєте за замовчуванням з 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 .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.