Je me demande s’il est possible de charger un objet qui a été décapé dans Python 2.4, avec Python 3.4.
J'ai utilisé 2to3 sur une grande quantité de code hérité de la société pour le mettre à jour.
Après avoir fait cela, lors de l’exécution du fichier, j’obtiens l’erreur suivante:
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)
En examinant l'objet en conflit, il s'agit d'une dict
dans un dict
, contenant des clés et des valeurs de type str
.
Ma question est donc la suivante: existe-t-il un moyen de charger un objet, initialement décapé dans python 2.4, avec python 3.4?
Vous devrez indiquer à pickle.load()
comment convertir Python les données de bytest en Python 3 chaînes, ou vous pouvez indiquer à pickle
de les conserver sous forme d'octets.
La valeur par défaut consiste à essayer de décoder toutes les données de chaîne au format ASCII. Ce décodage échoue. Voir la documentation pickle.load()
) :
Les arguments de mot clé facultatifs sont fix_imports , codant et erreurs , utilisées pour contrôler la compatibilité du flux de pickles généré par Python 2. Si fix_imports est vrai, cornichon essaiera de mapper les anciens noms Python 2 aux nouveaux noms utilisés dans Python 3. Le codage et des erreurs indiquent à pickle comment décoder des instances de chaînes de 8 bits sélectionnées par Python 2; Ces valeurs sont définies par défaut sur "ASCII" et "strict". Le codage peut être un "octet" pour lire ces occurrences de chaînes de 8 bits sous forme d’objets octets.
Définir le codage sur latin1
vous permet d'importer directement les données:
with open(mshelffile, 'rb') as f:
d = pickle.load(f, encoding='latin1')
mais vous devrez vérifier qu'aucune de vos chaînes n'est décodée à l'aide du mauvais codec; Latin-1 fonctionne pour toute entrée car il mappe directement les valeurs d'octet 0-255 aux 256 premiers points de code Unicode.
L'alternative serait de charger les données avec encoding='bytes'
et de décoder toutes les clés et valeurs bytes
par la suite.
Notez que jusqu’à Python versions antérieures à 3.6.8, 3.7.2 et 3.8.0, le dépickage de Python 2 datetime
les données de l’objet sont rompues = sauf si vous utilisez encoding='bytes'
.
L'utilisation de encoding = 'latin1' provoque certains problèmes lorsque votre objet contient des tableaux numpy.
Utiliser encoding = bytes sera mieux.
Veuillez voir ceci réponse pour une explication complète sur l’utilisation de encoding = bytes