2012-06-03 3 views
0

저는 현재 리눅스 (Ubuntu)에서 코딩/인코딩에 심각한 문제가 있습니다. 이전에는 그렇게 할 필요가 없었기 때문에 이것이 실제로 작동하지 않는 이유를 전혀 알지 못합니다!디코딩/인코딩 문제

나는 /usr/share/applications/에서 파일을 구문 분석하고 HTTPServer를 통해 웹 브라우저에 표시된 정보를 추출합니다. 나는 템플릿으로 jinja2을 사용하고 있습니다.

먼저, 난 단지 유니 코드 문자열을 반환

utf-8 cannot decode character XXX at position YY [...] 

그래서 내가합니다 (*.desktop 파일을 구문 분석하는) 내 appfind -module에서 오는 모든 값을 만들었다 고 말했다 jinja2.Template.render()에 대한 호출에 UnicodeDecodeError를 받았다.

이 곳의 문제는 지금까지 해결되었지만 어느 시점에 BaseHTTPServer.BaseHTTTPRequestHandler.wfile 슬롯에 함수에 의해 반환 된 문자열을 쓰고 있으며 어떤 인코딩을 사용 하던지이 오류를 수정할 수 없습니다.

이 시점에서 wfile에 쓰여진 문자열은 af34가 유니 코드 개체를 반환하는 jinja2.Template.render()에서옵니다.

기괴한 부분은 내 우분투 12.04 LTS에 있지만 내 친구의 우분투 11.04 LTS에 작동하는지입니다. 그러나 그 이유가 아닐 수도 있습니다. 그는 더 많은 응용 프로그램을 가지고 있으며 어쩌면 오류를 발생시키는 *.desktop 파일에 인코딩을 사용했을 수 있습니다.

data = dict(parser.items('Desktop Entry')) 

try: 
    encoding = data.get('encoding', 'utf-8') 
    result = { 
     'name':  data['name'].decode(encoding), 
     'exec':  DKENTRY_EXECREPL.sub('', data['exec']).decode(encoding), 
     'type':  data['type'].decode(encoding), 
     'version': float(data.get('version', 1.0)), 
     'encoding': encoding, 
     'comment': data.get('comment', '').decode(encoding) or None, 
     'categories': _filter_bool(data.get('categories', ''). 
             decode(encoding).split(';')), 
     'mimetypes': _filter_bool(data.get('mimetype', ''). 
             decode(encoding).split(';')), 
    } 

# ... 

누군가가 나는 내가이 오류를 해결할 수있는 방법에 대해 계몽시겠습니까 :

그러나, 나는 제대로 *.desktop 파일의 인코딩을 검사? 내가 항상 unicode()을 사용해야한다는 답변을 읽었지 만, 구현하기가 너무 힘들어서 wfile에 글을 쓸 때 문제가 해결되지 않을 것이라고 생각하십니까?

감사합니다,
니클라스

+1

'wfile'에 쓸 때 어떤 오류가 있습니까? – JAB

답변

1

바이트 문자열과 유니 코드 문자열에 대해 체계적인 접근 방식을 취해야합니다. 이것은 모두 설명합니다 : Pragmatic Unicode, or, How Do I Stop the Pain?

+0

멋진 요약, 감사합니다! 나는 실제 코드를 확인하고 다시 돌아올 것이다. –

3
이 아마 분명하다

하지만, 어쨌든이 :에 WFile는 일반 바이트 스트림 : 작성된 모든 unicode.encode해야합니다() : ED에 쓸 때.

OP를 읽으면, 나에게 정확히 무엇이 발생하는지 명확하지 않습니다. 그러나 인코딩 문제를 디버깅하는 데 도움이되는 몇 가지 트릭이 도움이 될 수 있습니다. 이것이 오랫동안 초월해온 물건이라면 미리 사과드립니다. 파일에

  • cat -v 출력합니다 '^ X'난 정말이 파일을 인코딩을 결정할 발견 한 유일한 바보 - 증거 방법입니다있는 모든 비 ASCII 문자. UTF-8 비 ASCII 문자는 멀티 바이트입니다. 즉, 그들은 하나 이상의 '^'항목의 시퀀스가 ​​cat -v에 있음을 의미합니다.

  • 쉘 환경 (LC_ALL, et al)은 제 경험상 가장 일반적인 문제의 원인입니다. UTF-8과 같은 로케일을 가진 시스템이 있는지 확인하십시오. 라틴 -1 사용 가능. 항상은 LC_ALL을 명시 적으로 인코딩 이름을 지정하는 로캘로 설정합니다 (예 : LC_ALL=sv_SE.iso88591.이것은 다른 로케일을 수출하는 것보다 테스트하기가 훨씬 쉬워집니다

    $ LC_ALL=sv_SE.utf8 python ./foo.py 
    

    을하고 :

    의 bash 및 zsh을에서
  • , 당신과 같이, 그 명령에 대한 고유의 환경 변화에 명령을 실행할 수 있습니다 쉘을 오염시키지 않을 것이다.

  • 내부적으로 유니 코드 문자열이 있다고 가정하지 마십시오. 문자열이 유니 코드인지 확인하는 assert 문을 작성하십시오.

    assert isinstance(foo, unicode) 
    
  • 이 엉망이 인식 알아보기/작업중인 인코딩의 일반적인 문자의 버전을 잘못. 예 : '\ xe4'는 latin-1 a diaresis이고 'ä'는 latin-1로 misstakenly 표현 된 diaresis를 구성하는 두 개의 UTF-8 바이트입니다. 나는 이런 종류의 고프를 알고 있으면 인코딩 문제를 상당히 디버깅 할 수 있다는 것을 알았다.

0

기본적으로 파이썬이 유니 코드로 인코딩 문제를 해결하면 오류가 발생합니다. 그러나 오류가 예상되거나 중요하지 않은 경우와 같이이 동작을 수정할 수 있습니다.

ascii의 상위 집합 인 두 개의 유니 코드 페이지간에 변환한다고 가정 해보십시오. 둘 다 대부분 같은 문자를 가지고 있지만 일대일 대응은 없습니다. 따라서 오류를 무시하고 싶을 것입니다.

이렇게하려면 인코딩 기능에서 errors 변수를 사용하십시오.

mystring = u'This is a test' 
print mystring.encode('utf-8', 'ignore') 
print mystring.encode('utf-8', 'replace') 
print mystring.encode('utf-8', 'xmlcharrefreplace') 
print mystring.encode('utf-8', 'backslashreplace') 

읽기/쓰기시 잘못된 인코딩을 사용하면 유니 코드와 관련하여 많은 문제가 있습니다. 유니 코드 문자열을 얻은 후에는 unicode desired by jinja2의 형식으로 변환해야합니다.

이 방법이 도움이되지 않는다면, 두 번째 오류를 추가하고 무슨 일이 벌어 졌는지 알려주는 코드 스 니펫을 추가 할 수 있습니까?

0

.decode(encoding) 대신 .encode(encoding)을 사용하십시오.