2012-04-07 12 views
13

Pracuję nad narzędziem Python, które musi otwierać pliki kodowania UTF-8 i UTF-16. W Pythonie 3.2, używam poniższy kod, żeby spróbować otworzyć plik za pomocą UTF-8, a następnie spróbuj go z UTF-16, czy jest jakiś błąd unicode:Jak mogę otworzyć pliki UTF-16 w Pythonie 2.x?

def readGridFromPath(self, filepath): 
    try: 
     self.readGridFromFile(open(filepath,'r',encoding='utf-8')) 
    except UnicodeDecodeError: 
      self.readGridFromFile(open(filepath,'r',encoding='utf-16')) 

(readGridFromFile albo będzie działać aż do zakończenia, lub podnieść a. UnicodeDecodeError)

jednak, kiedy uruchomić ten kod w Pythonie 2.x, otrzymuję:

TypeError: 'encoding' is an invalid keyword argument for this function 

widzę w docs że Python 2.x na open() nie ma encoding słowa kluczowego. Czy jest jakiś sposób obejścia tego, co pozwoli mi na kompatybilność mojego kodu Python 2.x?

Odpowiedz

20

io.open jest zamiennik dla swoich potrzeb, więc przykładowy kod podasz będzie wyglądać następująco w Pythonie 2.x:

import io 

def readGridFromPath(self, filepath): 
    try: 
     self.readGridFromFile(io.open(filepath, 'r', encoding='utf-8')) 
    except UnicodeDecodeError: 
     self.readGridFromFile(io.open(filepath, 'r', encoding='utf-16')) 


io.open opisano here w szczegółach. Prototyp jest:

io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)

io moduł sam został zaprojektowany jako warstwa kompatybilności pomiędzy Python 2.x Python 3.x, aby ułatwić przejście do Py3k i uproszczenie kopii przenoszenie i obsługę istniejących Pythonie 2.x.

Należy również pamiętać, że nie może być pewien wyjątek używając codecs.open, jak it works in binary mode only:

Note: Files are always opened in binary mode, even if no binary mode was specified. This is done to avoid data loss due to encodings using 8-bit values. This means that no automatic conversion of '\n'` is done on reading and writing.

również można uruchomić w kwestii ręcznie wykrywania i usuwania z UTF-8 BOM - codecs.open pozostawia UTF8 BOM inline jak u'\ufeff' charakterem .

+0

Dobre połączenie, 'io.open' jest lepszą opcją. Jednak wady "codecs.open" nie są wystarczająco znaczące, by nazwać je "nieodpowiednimi", IMHO. –

+0

Nawiasem mówiąc, twierdzenie dotyczące 'codecs.open' nie działa poprawnie BOM jest po prostu źle (próbowałem). Rzecz w tym, że nie automatycznie konwertuje znaki nowej linii jest prawdą (ale to chyba jedyna różnica). –

+0

Próbowałem już tego raz jeszcze - dla UTF-16 BE/LE działa całkiem dobrze, ale dla UTF8 jego BOM (EB BB BF) pozostaje w zdekodowanym tekście jako u '\ ubeff'. Pamiętam, że miałem problemy z dekodowaniem z BOM przy użyciu '.decode()' w systemie Windows, ale nie mogę go teraz przetestować. Naprawiłem to twierdzenie dla sprawiedliwości. – toriningen

Powiązane problemy