diff --git a/_posts/2017-01-22-json.md b/_posts/2017-01-22-json.md new file mode 100644 index 0000000..dfb3ef3 --- /dev/null +++ b/_posts/2017-01-22-json.md @@ -0,0 +1,181 @@ +--- +layout: post +slug: json +status: published +title: JSON simplement +description: Simplifiez-vous la vie +disqus: true +categories: +- code +tags: +--- + +Cet article a pour but d'expliquer ce qu'est JSON et de montrer des cas simples d'utilisation avec python. +Encore une fois, il n'est pas exhaustif et ne s'adresse pas à des experts. +Les exemples seront données avec python, mais JSON peut-être utilisé avec n'importe quel langage de programmation. + +JSON est une abbréviation qui signifie *JavaScript Object Notation*. +A vrai dire, ce n'est pas très important et ça ne nous informe pas particulièrement sur son usage. + +Prenons un exemple pour bien comprendre : + +## Le contexte : ma bibliothèque + +Imaginons que vous commenciez à faire l'inventaire des livres de votre bibliothèque en python : + +```python3 +# On créer un nouveau tableau qui contiendra nos livres +bibliotheque = [] +while True: + print(bibliotheque) + livre = input() + bibliotheque.append(livre) +``` + +Si on a le malheur d'arrêter l'application, alors on perd tout le contenu du tableau bibliothèque. +Et donc à chaque démarrage, on doit de nouveau rerentrer les livres. +Pas très pratique, mais il doit bien y avoir une solution ! + +## Ecrivons la liste des livres dans un fichier + +La solution est donc d'écrire la liste des livres dans un fichier. +Oui, mais c'est pas si simple. Comment je vais faire ? +Je vais séparer mes livres par des virgules ? Si mon titre contient une virgule, que va t'il se passer ? +Un livre sur chaque ligne alors ? Et si on veut rajouter d'autres informations après ? + +Mais ça veut dire que l'on va devoir écrire une fonction qui va convertir notre tableau en une chaine de caractère que l'on va enregistrer dans notre fichier, +ainsi qu'une autre fonction qui va lire une chaine de caractère d'un fichier et la transformer en fichier. + +Dans notre cas, c'est plutot simple mais ça peut vite se complexifier : + +```python3 +import os + +def sauvegarder(bibliotheque): + # --- on convertit bibliotheque (un tableau) en chaine de caractère --- + contenu = "" + for livre in bibliotheque: + # on ajoute à contenu un livre et un retour à la ligne + contenu += livre + "\n" + + # --- on sauvegarde la chaine de caractère --- + with open('sauvegarde.txt', 'w') as fichier: + fichier.write(contenu) + +def charger(): + # --- on lit le fichier --- + contenu = "" + with open('sauvegarde.txt') as fichier: + contenu = fichier.read() + + # --- on convertit la chaine de caractère en bibliotheque (tableau) --- + bibliotheque = contenu.split("\n") + return bibliotheque + +bibliotheque = [] + +# Si le fichier de sauvegarde existe, on le charge +if os.path.isfile('sauvegarde.txt'): + bibliotheque = charger() + +while True: + print(bibliotheque) + livre = input() + bibliotheque.append(livre) + + # on sauvegarde + sauvegarder(bibliotheque) +``` + +**Récapitulons :** + + * On doit convertir notre variable (tableau, dictionnaire) en chaine de caractère + * On doit écrire ou lire un fichier + +## Un modèle plus compliqué, impossible de convertir à la main le tableau en chaine de caractère + +Imaginons qu'à la place d'un simple titre, on veuille stocker plus d'informations : + +```python3 +# On créer un nouveau tableau qui contiendra nos livres +bibliotheque = [] +while True: + print(bibliotheque) + livre = {} # On créer un dictionnaire python + livre['titre'] = input("titre > ") + livre['auteur'] = input("auteur > ") + livre['edition'] = input("edition > ") +``` + +On devrait alors modifier les parties conversions des fonctions charger et sauvegarder. +Mais est-ce que l'ordinateur ne pourrait pas de lui-même convertir notre tableau en texte ? +Oui, on appelle ça sérializer et déserializer des données (magnifique anglicisme au passage). +Et JSON est une manière de faire ça, de convertir un tableau, un dictionnaire python, etc. en texte et vice-versa. + +## Découvrons JSON + +Donc JSON permets de convertir certaines variables (tableau, dictionnaire) en texte. +Voici un exemple avec notre bibliotheque + +```python3 +>>> import json +>>> bibliotheque = [] +>>> livre = {} +>>> livre['auteur'] = "J. K. Rowling" +>>> livre['titre'] = "Harry Potter 1" +>>> livre['edition'] = "Galimard" +>>> bibliotheque.append(livre) +>>> livre2['auteur'] = "Terry Pratchett" +>>> livre2 = {} +>>> livre2['auteur'] = "Terry Pratchett" +>>> livre2['titre'] = "Les annales du disque monde" +>>> livre2['edition'] = "Hachette" +>>> bibliotheque.append(livre2) +>>> json.dumps(bibliotheque) +'[{"edition": "Galimard", "titre": "Harry Potter 1", "auteur": "J. K. Rowling"}, {"edition": "Hachette", "titre": "Les annales du disque monde", "auteur": "Terry Pratchett"}]' +``` + +Tout en bas, la chaine de caractère, c'est la représentation JSON du contenu de votre variable bibliotheque. Copiez-collez le et ouvrez une nouvelle fenêtre python pour taper : + +```python3 +>>> import json +>>> bibliotheque = json.loads('[{"edition": "Galimard", "titre": "Harry Potter 1", "auteur": "J. K. Rowling"}, {"edition": "Hachette", "titre": "Les annales du disque monde", "auteur": "Terry Pratchett"}]') +>>> bibliotheque[0]['titre'] +'Harry Potter 1' +``` + +Voilà, votre tableau bibliothèque a été chargé avec le même contenu que tout à l'heure, sans que vous n'ayez vous même à convertir quoi que ce soit ! + +## Utiliser json avec des fichiers + +Si on voulait réécrire les fonction sauvegarde() et charger() précédentes, on pourrait utiliser les fonctions déjà existantes de json pour écrire dans un fichier. **Notez la présence d'un S à la fin dans `json.loads()` et `json.dumps() au dessus qui génèrent une chaine de caractère VS l'absence de ce S dans `json.load()` et `json.dump()` qui écrivent directement dans un fichier** + +```python3 +import json, os + +def sauvegarder(bibliotheque): + with open('sauvegarde.txt', 'w') as fichier: + json.dump(bibliotheque, fichier) + +def charger(): + with open('sauvegarde.txt') as fichier: + return json.load(fichier) + +# On créer un nouveau tableau qui contiendra nos livres +bibliotheque = [] + +if os.path.isfile('sauvegarde.txt'): + bibliotheque = charger() + +while True: + print(bibliotheque) + livre = {} # On créer un dictionnaire python + livre['titre'] = input("titre > ") + livre['auteur'] = input("auteur > ") + livre['edition'] = input("edition > ") + sauvegarder() +``` + +JSON ne sert pas qu'à sauvegarder des fichiers. Il permets aussi de faire communiquer des programmes écrits dans des langages différents via le réseau par exemple. + +Bon courage !