python - management - ConfigParser con elementos Unicode
load json config python (6)
El método ConfigParser.readfp()
puede tomar un objeto de archivo, ¿ha intentado abrir el objeto de archivo con la codificación correcta usando el módulo de códecs antes de enviarlo a ConfigParser como a continuación?
cfg.readfp(codecs.open("myconfig", "r", "utf8"))
Para Python 3.2 o superior, readfp()
está en desuso. Utilice read_file()
lugar.
Mis problemas con ConfigParser continúan. Parece que no soporta muy bien Unicode. El archivo de configuración se guarda de hecho como UTF-8, pero cuando ConfigParser lo lee, parece estar codificado en otra cosa. Asumí que era latin-1 y pensé que la optionxform
podría ayudar:
-- configfile.cfg --
[rules]
Häjsan = 3
☃ = my snowman
-- myapp.py --
# -*- coding: utf-8 -*-
import ConfigParser
def _optionxform(s):
try:
newstr = s.decode(''latin-1'')
newstr = newstr.encode(''utf-8'')
return newstr
except Exception, e:
print e
cfg = ConfigParser.ConfigParser()
cfg.optionxform = _optionxform
cfg.read("myconfig")
Por supuesto, cuando leo la configuración me sale:
''ascii'' codec can''t decode byte 0xc3 in position 0: ordinal not in range(128)
He intentado un par de variaciones diferentes de decodificación, pero el punto parece discutible, ya que realmente debería ser un objeto Unicode desde el principio. Después de todo, ¿el archivo de configuración es UTF-8? He confirmado que algo está mal en la forma en que ConfigParser lee el archivo al apagarlo con esta clase DummyConfig. Si uso eso, entonces todo está bien Unicode, fino y elegante.
-- config.py --
# -*- coding: utf-8 -*-
apa = {''rules'': [(u''Häjsan'', 3), (u''☃'', u''my snowman'')]}
class DummyConfig(object):
def sections(self):
return apa.keys()
def items(self, section):
return apa[section]
def add_section(self, apa):
pass
def set(self, *args):
pass
Cualquier idea que pueda estar causando esto o las sugerencias de otros módulos de configuración que soportan mejor Unicode son bienvenidas. No quiero usar sys.setdefaultencoding()
!
El módulo de configuración está roto al leer y escribir cadenas de Unicode como valores. Intenté arreglarlo, pero me quedé atrapado de la extraña manera en que funciona el analizador.
En Python 3.2, el parámetro de encoding
se introdujo en read()
, por lo que ahora se puede utilizar como:
cfg.read("myconfig", encoding=''utf-8'')
Intente sobrescribir la función de write
en RawConfigParser()
esta manera:
class ConfigWithCoder(RawConfigParser):
def write(self, fp):
"""Write an .ini-format representation of the configuration state."""
if self._defaults:
fp.write("[%s]/n" % "DEFAULT")
for (key, value) in self._defaults.items():
fp.write("%s = %s/n" % (key, str(value).replace(''/n'', ''/n/t'')))
fp.write("/n")
for section in self._sections:
fp.write("[%s]/n" % section)
for (key, value) in self._sections[section].items():
if key == "__name__":
continue
if (value is not None) or (self._optcre == self.OPTCRE):
if type(value) == unicode:
value = ''''.join(value).encode(''utf-8'')
else:
value = str(value)
value = value.replace(''/n'', ''/n/t'')
key = " = ".join((key, value))
fp.write("%s/n" % (key))
fp.write("/n")
Lo que hice es solo
file_name = file_name.decode("utf-8")
cfg.read(file_name)
Parece ser un problema con la versión ConfigParser para python 2x, y la versión para 3x está libre de este problema. En este número de Python Bug Tracker , el estado es Closed + WONTFIX.
Lo he arreglado editando el archivo ConfigParser.py. En el método de escritura (sobre la línea 412), cambie:
key = " = ".join((key, str(value).replace(''/n'', ''/n/t'')))
por
key = " = ".join((key, str(value).decode(''utf-8'').replace(''/n'', ''/n/t'')))
No sé si es una solución real, pero probada en Windows 7 y Ubuntu 15.04, funciona como un encanto, y puedo compartir y trabajar con el mismo archivo .ini en ambos sistemas.