python python-3.x pickle python-2.4 python-2to3

Desenganchar un objeto de Python 2 con Python 3



python-3.x pickle (2)

Me pregunto si hay una manera de cargar un objeto que se encurtió en Python 2.4, con Python 3.4.

He estado ejecutando 2to3 en una gran cantidad de código heredado de la compañía para actualizarlo.

Una vez hecho esto, cuando ejecuto el archivo aparece el siguiente error:

File "H:/fixers - 3.4/addressfixer - 3.4/trunk/lib/address/address_generic.py" , line 382, in read_ref_files d = pickle.load(open(mshelffile, ''rb'')) UnicodeDecodeError: ''ascii'' codec can''t decode byte 0xe2 in position 1: ordinal not in range(128)

Mirando el objeto encurtido en contención, es un dict en un dict , que contiene claves y valores de tipo str .

Entonces mi pregunta es: ¿hay alguna manera de cargar un objeto, originalmente en escabeche en Python 2.4, con Python 3.4?


El uso de encoding = ''latin1'' causa algunos problemas cuando su objeto contiene matrices numpy en él.

Usar encoding = bytes será mejor.

Consulte esta answer para obtener una explicación completa del uso de encoding = bytes


Tendrá que decirle a pickle.load() cómo convertir los datos de la cadena de bytes de Python a cadenas de Python 3, o puede decirle a pickle que los deje como bytes.

El valor predeterminado es intentar decodificar todos los datos de cadena como ASCII, y esa decodificación falla. Consulte la documentación de pickle.load() :

Los argumentos opcionales de palabras clave son fix_imports , codificación y errores , que se utilizan para controlar el soporte de compatibilidad para el flujo de pickle generado por Python 2. Si fix_imports es verdadero, pickle intentará asignar los nombres antiguos de Python 2 a los nuevos nombres utilizados en Python 3. El la codificación y los errores le indican a pickle cómo decodificar instancias de cadena de 8 bits encurtidas por Python 2; estos predeterminados a ''ASCII'' y ''estricto'', respectivamente. La codificación puede ser ''bytes'' para leer estas instancias de cadena de 8 bits como objetos de bytes.

Establecer la codificación en latin1 permite importar los datos directamente:

with open(mshelffile, ''rb'') as f: d = pickle.load(f, encoding=''latin1'')

pero deberá verificar que ninguna de sus cadenas esté decodificada usando el códec incorrecto; Latin-1 funciona para cualquier entrada, ya que asigna los valores de bytes 0-255 a los primeros 256 puntos de código Unicode directamente.

La alternativa sería cargar los datos con encoding=''bytes'' y descodificar todas las claves y valores de bytes posteriormente.

Tenga en cuenta que hasta las versiones de Python anteriores a 3.6.8, 3.7.2 y 3.8.0, el desempaquetado de los datos del objeto de datetime de Python 2 está roto a menos que use encoding=''bytes'' .