代码之家  ›  专栏  ›  技术社区  ›  pojo

带Unicode项的ConfigParser

  •  20
  • pojo  · 技术社区  · 15 年前

    我对配置共享器的问题还在继续。它似乎不太支持Unicode。配置文件确实保存为utf-8,但是当configparser读取它时,它似乎被编码成了其他东西。我以为那是拉丁语-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?我已经确认了configparser读取文件的方式有问题,方法是用这个dummonfig类将其存根删除。如果我用它,那么一切都是美好的Unicode,美好和花哨。

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

    6 回复  |  直到 6 年前
        1
  •  20
  •   Christina    10 年前

    这个 ConfigParser.readfp() 方法可以获取一个文件对象,在将其发送到configParser之前,是否尝试使用编解码器模块以正确的编码打开该文件对象,如下所示:

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

    对于python 3.2或更高版本, readfp() 被贬低。使用 read_file() 相反。

        2
  •  2
  •   user1438038    7 年前

    尝试覆盖 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")
    
        3
  •  1
  •   Ken Arnold    13 年前

    当以值的形式读取和写入Unicode字符串时,配置模块被中断。我试图修复它,但被解析器的工作方式搞得很奇怪。

        4
  •  1
  •   neogurb    9 年前

    对于python 2x的configparser版本似乎有问题,3x的版本没有这个问题。在 this issue of the Python Bug Tracker ,状态为关闭+Wontfix。

    我已经修复了编辑configparser.py文件的问题。在写入方法(关于第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中测试过,工作起来很有魅力,我可以在两个系统中共享和使用相同的.in i文件。

        5
  •  1
  •   Krzysztof Słowiński    6 年前

    在Python 3.2中 encoding 参数被引入 read() ,因此它现在可以用作:

    cfg.read("myconfig", encoding='utf-8')
    
        6
  •  0
  •   president    6 年前

    我所做的只是:

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