Python >> Tutoriel Python >  >> Python

Comment sérialiser un Python Dict dans une chaîne et inversement ?

Formulation du problème

Étant donné un dictionnaire Python contenant des listes et d'autres structures de données. Vous souhaitez stocker le dictionnaire dans un fichier ou l'envoyer sur le réseau sous une forme plus efficace.

Comment sérialiser un dictionnaire Python en une chaîne, puis désérialiser la chaîne en une structure de données de dictionnaire ?

Voici un exemple approximatif de ce que vous voulez faire :

Serialization Example
Input: {'Hello': [1, 2, 3], 42: 'World'}
Output: <some serialized form>

Deerialization Example
Input: <some serialized form>
Output: {'Hello': [1, 2, 3], 42: 'World'}

Alors, plongeons tout de suite dans la solution la plus Pythonique !

Sérialiser et désérialiser un dict avec Pickle

Pour sérialiser un dictionnaire donné d , importez simplement le pickle module avec import pickle , et attribuez le résultat de pickle.dumps(d) à une variable. Cette variable contiendra alors une chaîne binaire sérialisée que vous pourrez utiliser pour stocker le dictionnaire sur votre ordinateur ou l'envoyer sur le réseau.

import pickle


d = {'Hello': [1, 2, 3], 42: 'World'}
serialized_d = pickle.dumps(d)

Si vous imprimez la variable de chaîne, vous obtiendrez une sortie de chaîne binaire illisible représentant le dictionnaire sérialisé :

print(serialized_d)
# b'\x80\x04\x95!\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x05Hello\x94]\x94(K\x01K\x02K\x03eK*\x8c\x05World\x94u.'

Pour désérialiser la chaîne binaire créée par pickle.dumps() et créez un nouvel objet dictionnaire à partir de celui-ci, utilisez le pickle.loads() et transmettez-y la représentation de chaîne binaire sérialisée. La sortie est un nouvel objet dictionnaire différent du dictionnaire non sérialisé d'origine.

deserialized_d = pickle.loads(serialized_d)
print(deserialized_d)
# {'Hello': [1, 2, 3], 42: 'World'}

Pour résumer, c'est la manière la plus Pythonique de sérialiser et désérialiser un dictionnaire Python :

import pickle


d = {'Hello': [1, 2, 3], 42: 'World'}

# Serialize Dict
serialized_d = pickle.dumps(d)
print(serialized_d)
# b'\x80\x04\x95!\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x05Hello\x94]\x94(K\x01K\x02K\x03eK*\x8c\x05World\x94u.'

# Deserialize Dict
deserialized_d = pickle.loads(serialized_d)
print(deserialized_d)
# {'Hello': [1, 2, 3], 42: 'World'}

Vous pouvez confirmer que le dictionnaire d'origine et le dictionnaire désérialisé sont des copies mais ne pointent pas vers le même objet en utilisant le is opérateur :

print(d is deserialized_d)
# False

Mais considérez aussi une alternative simple sans bibliothèque !

Sérialiser et désérialiser un dict – Quick and Dirty No-Library

Pour sérialiser un dict Python en utilisant aucune dépendance externe et de manière lisible par l'homme, convertissez simplement la chaîne en dictionnaire à l'aide de la fonction intégrée str() . Pour désérialiser ce retour, transmettez la représentation sous forme de chaîne du dict dans le eval() intégré fonction qui renverra un nouvel objet dictionnaire qui est une copie de l'original.

d = {'Hello': [1, 2, 3], 42: 'World'}

# Serialize Dict
serialized_d = str(d)
print(serialized_d)

# Deserialize Dict
deserialized_d = eval(serialized_d)
print(deserialized_d)

L'avantage de cette méthode est qu'elle est simple et ne nécessite pas de bibliothèque. Le dictionnaire sérialisé est également lisible par l'homme. Cependant, c'est très inefficace par rapport à la méthode précédente car la chaîne sérialisée comporte beaucoup de surcharge inutile qui est optimisée avec pickle .

Python eval(s) est une fonction intégrée qui analyse l'argument de chaîne s dans une expression Python, l'exécute et renvoie le résultat de l'expression. Vous pouvez regarder ma vidéo explicative sur cette fonction particulière ici :

Autres alternatives

Pour plus de clarté, il convient de mentionner que deux alternatives existent :

  • https://docs.python.org/2/library/ast.html
  • https://pypi.org/project/PyYAML/

Les deux fournissent également des fonctionnalités de sérialisation/désérialisation.