Jestem naprawdę mylony z codecs.open function
. Kiedy robię:
file = codecs.open("temp", "w", "utf-8")
file.write(codecs.BOM_UTF8)
file.close()
Daje mi to błąd
UnicodeDecodeError: Kodek „ascii” nie może dekodować bajtu 0xef w pozycji 0: porządek poza zakresem (128)
Jeśli zrobię:
file = open("temp", "w")
file.write(codecs.BOM_UTF8)
file.close()
To działa dobrze.
Pytanie brzmi, dlaczego pierwsza metoda zawodzi? A jak wstawić BOM?
Jeśli druga metoda jest poprawna, to po co codecs.open(filename, "w", "utf-8")
?
python
utf-8
byte-order-mark
John Jiang
źródło
źródło
Odpowiedzi:
Myślę, że problem polega na tym, że
codecs.BOM_UTF8
jest to ciąg bajtów, a nie ciąg Unicode. Podejrzewam, że procedura obsługi plików próbuje zgadnąć, co naprawdę masz na myśli na podstawie „Mam pisać Unicode jako tekst zakodowany w UTF-8, ale dałeś mi ciąg bajtów!”Spróbuj napisać ciąg Unicode dla znaku kolejności bajtów (tj. Unicode U + FEFF), aby plik po prostu kodował go jako UTF-8:
(To wydaje się dawać właściwą odpowiedź - plik z bajtami EF BB BF.)
EDYCJA: Sugestia S. Lott, aby użyć „utf-8-sig” jako kodowania, jest lepsza niż bezpośrednie pisanie BOM, ale zostawię tę odpowiedź tutaj, ponieważ wyjaśnia ona, co wcześniej się nie udawało.
źródło
codecs.open
zamiast po prostuopen
Przeczytaj następujące: http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig
Zrób to
Plik wynikowy to UTF-8 z oczekiwanym zestawieniem komponentów.
źródło
temp.close()
?open
.@ S-Lott podaje właściwą procedurę, ale rozwijając kwestie związane z Unicode , Python interpreter może zapewnić więcej informacji.
Jon Skeet ma rację (nietypowy) w odniesieniu do
codecs
modułu - zawiera ciągi bajtów:Wybierając inną nit,
BOM
ma standardową nazwę Unicode i można ją wprowadzić jako:Jest również dostępny przez
unicodedata
:źródło
Używam polecenia file * nix do konwersji nieznanego pliku zestawu znaków w plik utf-8
źródło
# coding: utf8
zamiast tego# -*- coding: utf-8 -*-
jest o wiele łatwiejsze do zapamiętania.