Preservar caso no ConfigParser?


90

Tentei usar o módulo ConfigParser do Python para salvar as configurações. Para meu aplicativo, é importante que eu preserve a caixa de cada nome em minhas seções. Os documentos mencionam que passar str () para ConfigParser.optionxform () faria isso, mas não funciona para mim. Os nomes estão todos em minúsculas. Estou esquecendo de algo?

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

Pseudocódigo Python do que obtenho:

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')]

Respostas:


114

A documentação é confusa. O que eles querem dizer é:

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')

Ou seja, substituir optionxform, em vez de chamá-lo; a sobreposição pode ser feita em uma subclasse ou na instância. Ao substituir, defina-o como uma função (em vez do resultado da chamada de uma função).

Agora eu relatei isso como um bug , e desde então foi corrigido.


Obrigado. Funciona e concordo que os documentos são confusos.
pojo

39

Para mim, trabalhei para definir o optionxform imediatamente após criar o objeto

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

2
Funciona bem! (observe que no python 3 é o nome da classe "configparser" (sem maiúsculas)
Noam Manos

1
@NoamManos: Você está se referindo ao nome do módulo (o nome da classe ainda é ConfigParser ).
Jonas Byström

2
Observe que também funciona comConfigParser.ConfigParser()
Jean-François T.

De fato. Funciona. É bom mencionar que este parâmetro não está associado essencialmente a RawConfigParser (), já que também é compatível com a classe ConfigParser (). Obrigado cara.
ivanleoncz

7

Adicione ao seu código:

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

1
Isso parece funcionar para mim pelo menos no python 2.7 e é muito mais limpo do que a resposta aceita. Obrigado foo!
hrbdg

2
esta é a mesma resposta com pontuação mais alta - ver linha config.optionxform=str:) apenas em vez de lamdba @Martin v. Löwis usa strfunção incorporada
xuthus

@xuthus - Na verdade, você pode usar 11 linhas de código em vez de 1 linha. Como você quiser.
FooBar167

4

Eu sei que esta pergunta foi respondida, mas pensei que algumas pessoas poderiam achar esta solução útil. Esta é uma classe que pode facilmente substituir a classe ConfigParser existente.

Editado para incorporar a sugestão de @OozeMeister:

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

O uso é igual ao do ConfigParser normal.

parser = CaseConfigParser()
parser.read(something)

Isso evita ter que definir o optionxform toda vez que fizer um novo ConfigParser, o que é entediante.


Como optionxformé apenas um método no RawConfigParser, se você for tão longe quanto criar sua própria subclasse, você deve apenas substituir o método na subclasse em vez de redefini-lo por instanciação:class CaseConfigParser(ConfigParser): def optionxform(self, optionstr): return optionstr
OozeMeister

@OozeMeister ótima ideia!
icedtrees de

2

Embargo:

Se você usar padrões com ConfigParser, ou seja:

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

e tente tornar o analisador sensível a maiúsculas e minúsculas usando o seguinte:

config.optionxform = str

todas as opções do (s) arquivo (s) de configuração manterão a caixa, mas FOO_BAZserão convertidas em minúsculas.

Para que os padrões também mantenham o caso, use subclasses como na resposta @icedtrees:

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

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

Agora FOO_BAZmanterá a caixa e você não terá InterpolationMissingOptionError .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.