25

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」のデコードのさまざまなバリエーションをいくつか試しましたが、実際には最初から Unicode オブジェクトである必要があるため、その点は議論の余地があるようです。やっぱり設定ファイルはUTF-8なの?この DummyConfig クラスを使用してファイルをスタブ化することにより、ConfigParser がファイルを読み取る方法に問題があることを確認しました。私がそれを使用すると、すべてが素敵なユニコードであり、素晴らしくてダンディです.

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

4

5 に答える 5

22

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

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

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

于 2009-10-30T09:44:13.633 に答える
2

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

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")
于 2017-07-26T09:53:21.227 に答える