2012-04-07 15 views
13

Estoy trabajando en una herramienta de Python que debe poder abrir archivos de codificación UTF-8 y UTF-16. En Python 3.2, utilizo el siguiente código para tratar de abrir el archivo con codificación UTF-8, a continuación, tratar con UTF-16 si hay un error de Unicode:¿Cómo puedo abrir archivos UTF-16 en 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, o bien ejecutar hasta el final, o subir . una UnicodeDecodeError)

sin embargo, cuando ejecuta este código en Python 2.x, me sale:

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

que ver en la documentación que Python 2.x de open() no tiene una palabra clave encoding. ¿Hay alguna forma de evitar esto que me permita hacer compatible mi código Python 2.x?

Respuesta

20

io.open es muestra de gota en el reemplazo para sus necesidades, por lo que nos ha facilitado código se verá de la siguiente manera en 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 se describe en detalle here. Su prototipo es:

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

io propio módulo fue diseñado como capa de compatibilidad entre 2.x Python 3.x Python, para facilitar la transición a Py3k y simplificar back-portabilidad y mantenimiento de código 2.x Python existente.

Además, tenga en cuenta que no puede haber una advertencia usando codecs.open, como 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.

También es posible que encuentre problemas de detección y excluyendo la UTF8 BOM manualmente - codecs.open deja UTF8 BOM en línea como u'\ufeff' carácter .

+0

Buena llamada, 'io.open' es la mejor opción. Sin embargo, las desventajas de 'codecs.open' no son lo suficientemente importantes como para llamarlo" inadecuado ", en mi humilde opinión. –

+0

Por cierto, la afirmación sobre 'codecs.open' que no maneja la BOM correctamente es simplemente incorrecta (lo intenté). Sin embargo, el hecho de que no se conviertan automáticamente líneas nuevas es cierto (pero esta parece ser la única diferencia). –

+0

Lo he intentado de nuevo, para UTF-16 BE/LE funciona bastante bien, pero para UTF8 su BOM (EB BB BF) se deja en texto decodificado como u '\ ubeff'. Recuerdo claramente que tuve problemas de decodificación con BOM utilizando '.decode()' en Windows, pero no puedo probarlo ahora. He solucionado ese reclamo por justicia. – toriningen

Cuestiones relacionadas