2009-06-12 8 views
8

Używam Pythona 2.5. Co tu się dzieje? Co źle zrozumiałem? Jak mogę to naprawić?Problem UTF-8 w pytonie podczas czytania znaków

in.txt:

Stäckövérfløw 

code.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
print """Content-Type: text/plain; charset="UTF-8"\n""" 
f = open('in.txt','r') 
for line in f: 
    print line 
    for i in line: 
     print i, 
f.close() 

wyjściowa:

Stäckövérfløw 

S t � � c k � � v � � r f l � � w 

Odpowiedz

14
for i in line: 
    print i, 

Podczas odczytu pliku, łańcuch można przeczytać w to ciąg bajtów. Pętla for iteruje po jednym bajcie naraz. Powoduje to problemy z zakodowanym łańcuchem UTF-8, gdzie znaki spoza ASCII są reprezentowane przez wiele bajtów. Jeśli chcesz pracować z obiektami Unicode, gdzie znaki są podstawowe elementy, należy użyć

import codecs 
f = codecs.open('in', 'r', 'utf8') 

jeśli sys.stdout nie mają już odpowiedni zestaw kodowania, może trzeba go owinąć:

sys.stdout = codecs.getwriter('utf8')(sys.stdout) 
+0

dzięki, na miejscu! – jacob

+3

Parametr 'r' w 'codecs.open' faktycznie oznacza 'rb' (bez '\ n' konwersji) – jfs

1

to sprawdzić:

# -*- coding: utf-8 -*- 
import pprint 
f = open('unicode.txt','r') 
for line in f: 
    print line 
    pprint.pprint(line) 
    for i in line: 
     print i, 
f.close() 

Zwraca to:

StackOverflow
'St \ xc3 \ xa4ck \ xc3 \ xb6v \ xc3 \ xa9rfl \ xc3 \ xb8w'
S t? ? c k? ? v? ? r f l? ? w

Chodzi o to, że plik jest właśnie odczytywany jako ciąg bajtów. Iteracja nad nimi dzieli znaki wielobajtowe na bezsensowne wartości bajtów.

+0

TAK dla hurtig hjælp! – jacob

2

Zamiast tego użyj codecs.open, to działa dla mnie.

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
print """Content-Type: text/plain; charset="UTF-8"\n""" 
f = codecs.open('in','r','utf8') 
for line in f: 
    print line 
    for i in line: 
     print i, 
f.close() 
1
print c, 

Dodaje "pusty charrecter" i łamie prawidłowe sekwencje utf-8 na niepoprawne. Więc to nie będzie działać, chyba że piszesz signle bajt do wyjścia

sys.stdout.write(i) 
0

Jeden może chcesz po prostu użyć

f = open('in.txt','r') 
for line in f: 
    print line 
    for i in line.decode('utf-8'): 
     print i, 
f.close() 
Powiązane problemy