2016-08-10 31 views
5

Próbuję uzyskać bardzo prosty przykład na OSXie z pythonem 3.5.1, ale naprawdę jestem zablokowany. Czytałem tak wiele artykułów, które dotyczą podobnych problemów, ale nie mogę tego naprawić samodzielnie. Czy masz jakieś wskazówki, jak rozwiązać ten problem?Python3: UnicodeEncodeError: Kodek 'ascii' nie może kodować znaków ' xfc'

Chciałbym mieć prawidłowe zakodowane wyjście latin-1 zdefiniowane w mojej liście bez żadnych błędów.

Mój kod:

# coding=<latin-1> 

mylist = [u'Glück', u'Spaß', u'Ähre',] 
print(mylist) 

Błąd:

Traceback (most recent call last): 
File "/Users/abc/test.py", line 4, in <module> 
print(mylist) 
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in position 4: ordinal not in range(128) 

Jak można naprawić ten błąd, ale jeszcze dostać coś z stdout (drukowanymi literami):

mylist = [u'Glück', u'Spaß', u'Ähre',] 
    for w in mylist: 
     print(w.encode("latin-1")) 

Co otrzymuję jako wyjście:

b'Gl\xfcck' 
b'Spa\xdf' 
b'\xc4hre' 

Co locale 'pokazuje mi:

LANG="de_AT.UTF-8" 
LC_COLLATE="de_AT.UTF-8" 
LC_CTYPE="de_AT.UTF-8" 
LC_MESSAGES="de_AT.UTF-8" 
LC_MONETARY="de_AT.UTF-8" 
LC_NUMERIC="de_AT.UTF-8" 
LC_TIME="de_AT.UTF-8" 
LC_ALL= 

Co -> 'python3' pokazuje mi:

Python 3.5.1 (default, Jan 22 2016, 08:54:32) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys 
>>> sys.getdefaultencoding() 
'utf-8' 
+0

działa poprawnie na mojej wersji Pythona 3.4 Windows: mylist = [u'Glück 'u'Spaß', u'Ähre ”] dla spawa w listy podr: druku (w) wyjściowa: Glück Spaß Ähre więc tutaj nie ma problemu. Zauważ, że jeśli użyjesz 'encode', otrzymasz typ' bytes', który nie jest ci potrzebny. –

Odpowiedz

2

Usuń znaki < i >:

# coding=latin-1 

Znaki te są często używane w przykładach do wskazania, gdzie znajduje się nazwa kodowania, ale literalne znaki < i > nie powinny być zawarte w pliku.

Aby to działało, plik musi być zakodowany przy użyciu Latin-1. Jeśli plik jest rzeczywiście zakodowane przy użyciu UTF-8, linia kodowanie powinno być

# coding=utf-8 

Na przykład, kiedy uruchomić ten skrypt (zapisany jako plik z latin-1 kodowaniu):

# coding=latin-1 

mylist = [u'Glück', u'Spaß', u'Ähre',] 
print(mylist) 

for w in mylist: 
    print(w.encode("latin-1")) 

Otrzymuję to wyjście (bez błędów):

['Glück', 'Spaß', 'Ähre'] 
b'Gl\xfcck' 
b'Spa\xdf' 
b'\xc4hre' 

Ten wynik wygląda poprawnie. Na przykład kodowanie ü dla Latin-1 ü to '\xfc'.

Użyłem mojego edytora, aby zapisać plik z kodowaniem Latin-1. Zawartość pliku w szesnastkowym to:

$ hexdump -C codec-question.py 
00000000 23 20 63 6f 64 69 6e 67 3d 6c 61 74 69 6e 2d 31 |# coding=latin-1| 
00000010 0a 0a 6d 79 6c 69 73 74 20 3d 20 5b 75 27 47 6c |..mylist = [u'Gl| 
00000020 fc 63 6b 27 2c 20 75 27 53 70 61 df 27 2c 20 75 |.ck', u'Spa.', u| 
00000030 27 c4 68 72 65 27 2c 5d 0a 70 72 69 6e 74 28 6d |'.hre',].print(m| 
00000040 79 6c 69 73 74 29 0a 0a 66 6f 72 20 77 20 69 6e |ylist)..for w in| 
00000050 20 6d 79 6c 69 73 74 3a 0a 20 20 20 20 70 72 69 | mylist:. pri| 
00000060 6e 74 28 77 2e 65 6e 63 6f 64 65 28 22 6c 61 74 |nt(w.encode("lat| 
00000070 69 6e 2d 31 22 29 29 0a       |in-1")).| 
00000078 

Należy zauważyć, że pierwszy bajt (reprezentowany szesnastkowo) w trzeciej linii (to znaczy w postaci położenia 0x20) jest fc. To jest kodowanie ü dla Latin-1. Jeśli plik został zakodowany przy użyciu utf-8, znak ü byłby reprezentowany przy użyciu dwóch bajtów, c3 bc.

+0

Dziękujemy za szczegółowe wyjaśnienie! –

0

Spróbuj uruchomić skrypt z PYTHONENCODING = UTF-8:

PYTHONENCODING=utf-8 python3 scripy.py