Frage

meine Probleme mit ConfigParser fortzusetzen. Es scheint, es Unicode nicht unterstützt sehr gut. Die Konfigurationsdatei ist in der Tat als UTF-8 gespeichert, aber wenn ConfigParser es liest scheint es in etwas anderes codiert werden. Ich nahm an, es war Latein-1 und ich thougt optionxform zwingende könnte helfen:

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

Natürlich, wenn ich die Config lese ich bekommen:

'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

Ich habe ein paar verschiedene Variationen versucht der Decodierung ‚s‘ aber der Punkt scheint fraglich, da es wirklich ein Unicode-Objekt von Anfang an sein sollte. Schließlich ist die Config-Datei UTF-8? Ich habe bestätigt, dass etwas in der Art und Weise falsch ist ConfigParser liest die Datei, indem Sie sich mit dieser DummyConfig Klasse Anstoßen. Wenn ich das dann alles ist schön, Unicode, schön und gut.

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

Alle Ideen, was diese oder Vorschläge von anderen Konfigurationsmodule, die Unicode besser unterstützt verursachen könnten, sind sehr willkommen. Ich will nicht sys.setdefaultencoding() verwenden!

War es hilfreich?

Lösung

Die ConfigParser.readfp() Methode ein Dateiobjekt nehmen, haben Sie versucht, das Dateiobjekt mit der richtigen Codierung unter Verwendung des Codecs Modul zu öffnen, bevor es zu ConfigParser wie unten Senden:

cfg.readfp(codecs.open("myconfig", "r", "utf8"))

Für Python 3.2 oder höher, readfp() ist veraltet. Verwenden Sie read_file() statt.

Andere Tipps

Versuchen Sie, die write Funktion in RawConfigParser() wie diese zu überschreiben:

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

Das Konfigurationsmodul defekt ist beim Lesen und Unicode-Strings als Wert zu schreiben. Ich habe versucht, es zu beheben, werden aber in der seltsamen Art und Weise gefangen der Parser funktioniert.

Es scheint ein Problem mit der ConfigParser Version für Python 2x zu sein, und die Version für 3x ist dieses Problem frei. In dieser Ausgabe des Python Bug Tracker , ist der Status Geschlossen + WONTFIX.

Ich habe es Datei Bearbeiten der ConfigParser.py fixiert. Bei der Schreibmethode (über die Linie 412) ändern:

key = " = ".join((key, str(value).replace('\n', '\n\t')))

durch

key = " = ".join((key, str(value).decode('utf-8').replace('\n', '\n\t')))

Ich weiß nicht, ob es sich um eine wirkliche Lösung ist, aber in Windows 7 und Ubuntu 15.04, wirkt wie ein Zauber getestet, und ich kann in beiden Systemen mit der gleichen INI-Datei teilen und arbeiten.

In Python 3.2 encoding Parameter wurden read() eingeführt, so kann es jetzt als verwendet werden:

cfg.read("myconfig", encoding='utf-8')

, was ich tat, ist nur:

file_name = file_name.decode("utf-8")
cfg.read(file_name)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top