web-dev-qa-db-ja.com

Unicodeアイテムを含むConfigParser

configParserに関する私のトラブルは続きます。 Unicodeをうまくサポートしていないようです。構成ファイルは確かにUTF-8として保存されますが、ConfigParserがそれを読み取ると、別のファイルにエンコードされているように見えます。私はそれがlatin-1であると仮定し、optionxformをオーバーライドすると役立つ可能性があります。

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

もちろん、設定を読むと、次のようになります。

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

「s」をデコードするいくつかの異なるバリエーションを試しましたが、最初からユニコードオブジェクトである必要があるため、要点は議論の余地があるようです。結局のところ、設定ファイルはUTF-8ですか? ConfigParserがこのDummyConfigクラスでファイルをスタブアウトすることにより、ファイルを読み取る方法に問題があることを確認しました。私がそれを使用する場合、すべてが素敵なユニコードで、上質でダンディです。

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

これを引き起こしている可能性のあるアイデアや、Unicodeをより適切にサポートする他の構成モジュールの提案を歓迎します。 sys.setdefaultencoding()を使いたくない!

22
pojo

ConfigParser.readfp()メソッドはファイルオブジェクトを受け取ることができます。以下のようにConfigParserに送信する前に、コーデックモジュールを使用して正しいエンコーディングでファイルオブジェクトを開こうとしましたか。

_cfg.readfp(codecs.open("myconfig", "r", "utf8"))
_

Python 3.2以降の場合、 readfp() は非推奨です。代わりに read_file() を使用してください。

21
Tendayi Mawushe

python 3.2 encodingパラメータがread()に導入されたため、次のように使用できるようになりました。

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

RawConfigParser()write関数を次のように上書きしてみてください。

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")
2
LI ZHE

Unicode文字列を値として読み書きすると、configモジュールが壊れます。私はそれを修正しようとしましたが、パーサーが機能する奇妙な方法に巻き込まれました。

1
Ken Arnold

python 2xのConfigParserバージョンに問題があるようで、3xのバージョンにはこの問題はありません。 この問題のPython =バグトラッカー 、ステータスはクローズ+ WONTFIXです。

ConfigParser.pyファイルを編集して修正しました。 writeメソッド(412行目について)で、次を変更します。

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

沿って

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

それが本当の解決策かどうかはわかりませんが、Windows7とUbuntu15.04でテストされ、魅力のように機能し、両方のシステムで同じ.iniファイルを共有して操作できます。

1
neogurb

私がしたことはただです:

file_name = file_name.decode("utf-8")
cfg.read(file_name)
0
president