2012-04-07 17 views
13

Sto lavorando a uno strumento Python che deve essere in grado di aprire file di codifica UTF-8 e UTF-16. In Python 3.2, io uso il seguente codice per provare ad aprire il file utilizzando UTF-8, quindi provare con UTF-16 se c'è un errore di unicode:Come posso aprire file UTF-16 su Python 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 sarà o correre fino al suo completamento, o rilanciare . un UnicodeDecodeError)

Tuttavia, quando si esegue questo codice in Python 2.x, ottengo:

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

vedo nella documentazione che Python 2.x di open() non ha un encoding parola chiave. C'è un modo per aggirare questo che mi permetterà di rendere il mio codice Python 2.x compatibile?

risposta

20

io.open è rimpiazzo per le vostre esigenze, in modo da codice di esempio che ci hai fornito guarderà come segue in Python 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 è descritto here in dettaglio. Il suo prototipo è:

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

io modulo stesso è stato progettato come strato di compatibilità tra Python 2.xe Python 3.x, per facilitare la transizione a Py3k e semplificare back-porting e manutenzione di codice Python 2.x esistente.

Inoltre, si precisa che non ci può essere un avvertimento tramite codecs.open, come 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.

Inoltre si può incorrere in problemi di rilevazione e escludendo UTF8 BOM manualmente - codecs.open lascia UTF8 BOM linea come u'\ufeff' carattere .

+0

Una buona chiamata, 'io.open' è l'opzione migliore. Tuttavia, gli svantaggi di 'codecs.open' non sono abbastanza significativi da definirlo" inadatto ", IMHO. –

+0

A proposito, l'affermazione su 'codecs.open' che non gestisce correttamente la BOM è semplicemente sbagliata (l'ho provato). Il fatto non converte automaticamente le newline è vero (ma questa sembra essere l'unica differenza). –

+0

L'ho provato di nuovo adesso - per UTF-16 BE/LE funziona abbastanza bene, ma per UTF8 il suo BOM (EB BB BF) è lasciato nel testo decodificato come u '\ ubeff'. Ricordo chiaramente che avevo problemi di decodifica con BOM usando '.decode()' su Windows, ma non posso testarlo ora. Ho corretto questa richiesta di equità. – toriningen

Problemi correlati