2009-10-30 3 views
17

ConfigParser에서의 문제가 계속됩니다. 유니 코드를 잘 지원하지 않는 것 같습니다. 구성 파일은 실제로 UTF-8로 저장되지만, ConfigParser가 그것을 읽을 때 다른 것으로 인코딩 된 것 같습니다. 나는 라틴어-1이었다 가정 내가 도움이 될 수 optionxform을 무시 thougt : 물론유니 코드 항목이있는 ConfigParser

-- 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 클래스를 사용하여 파일을 스텁 (stubbing)하여 파일을 읽는 방식에 문제가 있다는 것을 확인했습니다. 그걸 사용하면 모든 것이 유니 코드, 멋지고 멋쟁이입니다.

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

이 아이디어를 유발할 수있는 아이디어 나 유니 코드를 더 잘 지원하는 다른 구성 모듈의 제안을 환영합니다. sys.setdefaultencoding()을 사용하고 싶지 않습니다!

+0

을 눈사람은 라틴어-1' – u0b34a0f6ae

+0

이제까지 Exception' 제외하고'행동을 절대하지 마십시오 '의 일부가 아닙니다; 당신이 처리하는 방법을 알고있는 실제 예외를 잡아라. –

답변

19

, 아래처럼 ConfigParser로 보내기 전에 코덱 모듈을 사용하여 올바른 인코딩 파일 객체를 여는 시도가 파일 객체를 취할 수있는 ConfigParser.readfp() 방법 : 위의

cfg.readfp(codecs.open("myconfig", "r", "utf8")) 
파이썬 3.2

또는 readfp()을 사용되지 않습니다. 대신 read_file()을 사용하십시오.

+1

나는 동일한 문제를 가지고 있으며 config 파일에서 READ하는 것과 같은 방법으로 해결했다. 그러나 나는 또한 그것의 수정 된 버전을 다시 작성해야합니다. 그리고 코덱을 사용하더라도 실패합니다. : conffile : config.write (conffile)로 codecs.open (filename, encoding = ENCODING, mode = 'wb' ' –

+0

안녕하세요 Ghislain, configparser에서 유니 코드 문자열을 다시 작성하는 것과 동일한 문제가 있습니다. 그것은 pip에 의해 최신 verion으로 업데이트함으로써 해결됩니다. – Erxin

1

유니 코드 문자열을 값으로 읽고 쓸 때 구성 모듈이 손상되었습니다. 나는 그것을 고치려고 노력했지만 파서가 이상한 방식으로 따라 잡았다.

1

python 2x 용 ConfigParser 버전에 문제가있는 것으로 보이며 3x 용 버전에는이 문제가 없습니다. this issue of the Python Bug Tracker에서 상태는 Closed + 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'))) 
이 가

나는 그것이 진정한 해결책인지 알고 있지만, 윈도우 7과 우분투 15.04에서 테스트하지 않습니다처럼 작동 두 시스템에서 같은 .ini 파일을 공유하고 사용할 수 있습니다.

2

시도는 다음과 같이 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") 
+0

RawConfigParser를 원숭이 패치 할 수도 있습니다 :'RawConfigParser.write = write' –