2010-02-03 10 views
6

Jak wymusić wyjście pliku Latin-1 (co, jak sądzę, oznacza iso-8859-1?) W Pythonie?Python: Jak wymusić wyjście pliku iso-8859-1?

Oto mój kod w tej chwili. Działa, ale próba importu wynikowego pliku do tabeli MySQL Latin-1 generuje weird encoding errors.

outputFile = file("textbase.tab", "w") 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write(complete_line) 
    outputFile.write("\n") 
outputFile.close() 

Powstały plik wyjściowy wydaje się być zapisane w „Zachodniej (Mac OS Roman)”, ale jeśli następnie zapisać go w Latin-1, wciąż otrzymuję dziwne problemy kodowania. Jak mogę się upewnić, że użyte ciągi i sam plik są zakodowane w Latin-1, gdy tylko zostaną wygenerowane?

Oryginalne ciągi (w słowniku textData) zostały przeanalizowane z pliku RTF - nie wiem, czy to ma znaczenie.

Jestem trochę nowy w Pythonie i ogólnie kodowania, więc przepraszam, jeśli to głupie pytanie. Próbowałem spojrzeć na dokumenty, ale nie zaszły daleko.

Używam Python 2.6.1.

Odpowiedz

10

Wystarczy użyć modułu codecs do zapisu pliku:

import codecs 
outputFile = codecs.open("textbase.tab", "w", "ISO-8859-1") 

Oczywiście, struny piszesz muszą być ciągi Unicode (typ unicode), nie zostaną zamienione, jeżeli są one gładkie str obiekty (które są w zasadzie po prostu tablicami bajtów). Sądzę, że czytasz plik RTF z normalnym obiektem pliku Python, więc możesz również przekonwertować to na używanie codecs.open.

0

myślę, że to po prostu:

outputFile = file("textbase.tab", "wb") 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write((complete_line + "\n").encode("iso-8859-1")) 
    outputFile.close() 

Jak wspomniałem, trzeba upewnić się, czy dekodowanie pliku RTF zbyt poprawnie. Aby to działało, k i v powinny być obiektami unikodowymi.

+0

Dziękuję. Właśnie próbowałem tego kodu, ale otrzymuję: "UnicodeDecodeError: kodek 'ascii' nie może dekodować bajtu 0xa3 w pozycji 753: porządkowy nie w zakresie (128)". Spróbuję teraz upewnić się, że k i v są obiektami unicode, jak zasugerowano powyżej. – AP257

0

Głównym problemem jest to, że nie wiesz, jakie jest kodowanie danych. Jeśli założymy, że masz rację pod tym względem, że Twój plik kończy się na Mac OS Roman, musisz najpierw zdekodować dane, aby najpierw unicode , a następnie zakoduj go jako iso-8859-1.

inputFile = open("input.rtf", "rb") # The b flag is just a marker in Python 2. 
data = inputFile.read().decode('mac_roman') 
textData = yourparsefunctionhere(data) 

outputFile = open("textbase.tab", "wb") # don't use file() 
for k, v in textData.iteritems(): 
    complete_line = k + '~~~~~' + v + '~~~~~' + " ENDOFTHELINE" 
    outputFile.write((complete_line + "\n").encode("iso-8859-1")) 
    outputFile.close() 

Ale nie byłbym zaskoczony, ponieważ jest to RTF, jeśli jest zakodowany w systemie Windows, więc możesz też spróbować. Nie wiem, jak RTF określa kodowanie.

+0

Jeśli użyjesz r zamiast rb, Windows zmapuje \ r \ n do \ r (włącznie z Pythonem 2.6). –

+0

Z dokumentacji: "Dołącz" b 'do trybu, aby otworzyć plik w trybie binarnym, w systemach, które rozróżniają pliki binarne i tekstowe, w systemach, które nie mają tego rozróżnienia, dodanie "b" nie ma żadnego efektu. " Posiadanie b lub t (lub żadnego z nich) nie robi żadnej różnicy na Uniksie. Być może myślisz o "U", który jest uniwersalnym newlinsem.* It * maches line-endings (nigdy nie masz przy pisaniu!) Jakie systemy rozróżniające tekst i pliki binarne, których nie znam. Unix z pewnością tego nie robi. –

0

Dla mnie io.open działa nieco szybciej na Pythona 2.7 do zapisu, a rząd wielkości szybciej brzmi:

import io 
with io.open("textbase.tab", "w", encoding="ISO-8859-1") as outputFile: 
    ... 

W Pythonie 3, można po prostu pass the encoding keyword arg to open ty.

Powiązane problemy