¿Conservar caso en ConfigParser?
-
05-07-2019 - |
Pregunta
He intentado usar el módulo ConfigParser de Python para guardar la configuración. Para mi aplicación es importante que guarde el caso de cada nombre en mis secciones. Los documentos mencionan que pasar str () a ConfigParser.optionxform () lograría esto, pero no funciona para mí. Los nombres son todos en minúscula. ¿Me estoy perdiendo algo?
<~/.myrc contents>
[rules]
Monkey = foo
Ferret = baz
Seudocódigo de Python de lo que obtengo:
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')]
Solución
La documentación es confusa. Lo que quieren decir es esto:
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')
I.e. invalide optionxform, en lugar de llamarlo; La anulación se puede hacer en una subclase o en la instancia. Al anularlo, configúralo en una función (en lugar del resultado de llamar a una función).
Ahora he informado esto como un error , y desde entonces se ha corregido.
Otros consejos
Trabajé para configurar optionxform inmediatamente después de crear el objeto
config = ConfigParser.RawConfigParser()
config.optionxform = str
Añade a tu código:
config.optionxform = lambda option: option # preserve case for letters
Sé que esta pregunta está respondida, pero pensé que algunas personas podrían encontrar útil esta solución. Esta es una clase que puede reemplazar fácilmente la clase ConfigParser existente.
Editado para incorporar la sugerencia de @ OozeMeister:
class CaseConfigParser(ConfigParser):
def optionxform(self, optionstr):
return optionstr
El uso es el mismo que el ConfigParser normal.
parser = CaseConfigParser()
parser.read(something)
Esto es para evitar tener que configurar optionxform cada vez que crea un nuevo ConfigParser
, que es un poco tedioso.
Advertencia:
Si usa valores predeterminados con ConfigParser, es decir:
config = ConfigParser.SafeConfigParser({'FOO_BAZ': 'bar'})
y luego intente hacer que el analizador distinga mayúsculas de minúsculas usando esto:
config.optionxform = str
todas sus opciones de archivos de configuración mantendrán su caso, pero FOO_BAZ
se convertirá a minúsculas.
Para que los valores predeterminados también conserven su caso, use subclases como en la respuesta @icedtrees:
class CaseConfigParser(ConfigParser.SafeConfigParser):
def optionxform(self, optionstr):
return optionstr
config = CaseConfigParser({'FOO_BAZ': 'bar'})
Ahora FOO_BAZ
mantendrá su caso y no tendrá InterpolationMissingOptionError .