Python orienté objet - Sérialisation d'objets

Dans le contexte du stockage de données, la sérialisation est le processus de traduction des structures de données ou de l'état des objets dans un format qui peut être stocké (par exemple, dans un fichier ou une mémoire tampon) ou transmis et reconstruit ultérieurement.

Lors de la sérialisation, un objet est transformé en un format qui peut être stocké, afin de pouvoir le désérialiser ultérieurement et recréer l'objet d'origine à partir du format sérialisé.

Cornichon

Le décapage est le processus par lequel une hiérarchie d'objets Python est convertie en un flux d'octets (généralement non lisible par l'homme) pour être écrit dans un fichier, cela est également connu sous le nom de sérialisation. Unpickling est l'opération inverse, par laquelle un flux d'octets est reconverti en une hiérarchie d'objets Python fonctionnelle.

Pickle est le moyen le plus simple sur le plan opérationnel de stocker l'objet. Le module Python Pickle est un moyen orienté objet de stocker des objets directement dans un format de stockage spécial.

Qu'est-ce que ça peut faire?

  • Pickle peut stocker et reproduire très facilement des dictionnaires et des listes.
  • Stocke les attributs d'objet et les restaure dans le même état.

Qu'est-ce que le cornichon ne peut pas faire?

  • Il n'enregistre pas un code d'objets. Seulement ses valeurs d'attributs.
  • Il ne peut pas stocker les descripteurs de fichiers ou les sockets de connexion.

En bref, nous pouvons dire que le décapage est un moyen de stocker et de récupérer des variables de données dans et hors de fichiers où les variables peuvent être des listes, des classes, etc.

Pour décaper quelque chose, vous devez -

  • importer des cornichons
  • Écrivez une variable dans un fichier, quelque chose comme
pickle.dump(mystring, outfile, protocol),

où le protocole du 3ème argument est facultatif Pour décoller quelque chose, vous devez -

Importer du cornichon

Ecrire une variable dans un fichier, quelque chose comme

myString = pickle.load(inputfile)

Méthodes

L'interface pickle propose quatre méthodes différentes.

  • dump() - La méthode dump () sérialise en un fichier ouvert (objet de type fichier).

  • dumps() - Sérialise en une chaîne

  • load() - Désérialise d'un objet de type ouvert.

  • loads() - Désérialise d'une chaîne.

Sur la base de la procédure ci-dessus, vous trouverez ci-dessous un exemple de «décapage».

Production

My Cat pussy is White and has 4 legs
Would you like to see her pickled? Here she is!
b'\x80\x03c__main__\nCat\nq\x00)\x81q\x01}q\x02(X\x0e\x00\x00\x00number_of_legsq\x03K\x04X\x05\x00\x00\x00colorq\x04X\x05\x00\x00\x00Whiteq\x05ub.'

Ainsi, dans l'exemple ci-dessus, nous avons créé une instance d'une classe Cat, puis nous l'avons décapée, transformant notre instance «Cat» en un simple tableau d'octets.

De cette façon, nous pouvons facilement stocker le tableau d'octets sur un fichier binaire ou dans un champ de base de données et le restaurer ultérieurement à sa forme d'origine à partir de notre support de stockage.

Aussi si vous voulez créer un fichier avec un objet pickled, vous pouvez utiliser la méthode dump () (au lieu des dumps * () * one) en passant également un fichier binaire ouvert et le résultat du pickling sera automatiquement stocké dans le fichier.

[….]
binary_file = open(my_pickled_Pussy.bin', mode='wb')
my_pickled_Pussy = pickle.dump(Pussy, binary_file)
binary_file.close()

Démêler

Le processus qui prend un tableau binaire et le convertit en une hiérarchie d'objets est appelé unpickling.

Le processus de décolmatage est effectué à l'aide de la fonction load () du module pickle et renvoie une hiérarchie d'objets complète à partir d'un simple tableau d'octets.

Utilisons la fonction de chargement dans notre exemple précédent.

Production

MeOw is black
Pussy is white

JSON

JSON (JavaScript Object Notation) a fait partie de la bibliothèque standard Python est un format léger d'échange de données. Il est facile pour les humains de lire et d'écrire. Il est facile à analyser et à générer.

En raison de sa simplicité, JSON est un moyen par lequel nous stockons et échangeons des données, ce qui est accompli grâce à sa syntaxe JSON, et est utilisé dans de nombreuses applications Web. Comme il est dans un format lisible par l'homme, et cela peut être l'une des raisons de son utilisation dans la transmission de données, en plus de son efficacité lors de l'utilisation des API.

Un exemple de données au format JSON est le suivant -

{"EmployID": 40203, "Name": "Zack", "Age":54, "isEmployed": True}

Python simplifie le travail avec les fichiers Json. Le module proposé à cet effet est le module JSON. Ce module doit être inclus (intégré) dans votre installation Python.

Voyons donc comment pouvons-nous convertir un dictionnaire Python en JSON et l'écrire dans un fichier texte.

JSON à Python

Lire JSON signifie convertir JSON en une valeur Python (objet). La bibliothèque json analyse JSON dans un dictionnaire ou une liste en Python. Pour ce faire, nous utilisons la fonction load () (charger à partir d'une chaîne), comme suit -

Production

Voici un exemple de fichier json,

data1.json
{"menu": {
   "id": "file",
   "value": "File",
   "popup": {
      "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
      ]
   }
}}

Le contenu ci-dessus (Data1.json) ressemble à un dictionnaire conventionnel. Nous pouvons utiliser pickle pour stocker ce fichier, mais la sortie de celui-ci n'est pas une forme lisible par l'homme.

JSON (Java Script Object Notification) est un format très simple et c'est l'une des raisons de sa popularité. Examinons maintenant la sortie json via le programme ci-dessous.

Production

Ci-dessus, nous ouvrons le fichier json (data1.json) pour la lecture, obtenons le gestionnaire de fichiers et passons à json.load et récupérons l'objet. Lorsque nous essayons d'imprimer la sortie de l'objet, c'est la même chose que le fichier json. Bien que le type de l'objet soit un dictionnaire, il se présente sous la forme d'un objet Python. Ecrire dans le json est simple comme nous l'avons vu ce cornichon. Ci-dessus, nous chargeons le fichier json, ajoutons une autre paire clé / valeur et l'écrivons dans le même fichier json. Maintenant, si nous voyons data1.json, il semble différent .ie pas dans le même format que nous voyons précédemment.

Pour rendre notre sortie identique (format lisible par l'homme), ajoutez le couple d'arguments dans notre dernière ligne du programme,

json.dump(conf, fh, indent = 4, separators = (‘,’, ‘: ‘))

De même que pickle, nous pouvons imprimer la chaîne avec des vidages et charger avec des charges. Voici un exemple de cela,

YAML

YAML est peut-être la norme de sérialisation de données la plus conviviale pour tous les langages de programmation.

Le module Python yaml s'appelle pyaml

YAML est une alternative à JSON -

  • Human readable code - YAML est le format le plus lisible par l'homme à tel point que même son contenu de première page est affiché en YAML pour faire valoir ce point.

  • Compact code - Dans YAML, nous utilisons l'indentation d'espaces blancs pour désigner la structure et non les crochets.

  • Syntax for relational data - Pour les références internes, nous utilisons des ancres (&) et des alias (*).

  • One of the area where it is used widely is for viewing/editing of data structures - par exemple les fichiers de configuration, le vidage pendant le débogage et les en-têtes de documents.

Installation de YAML

Comme yaml n'est pas un module intégré, nous devons l'installer manuellement. La meilleure façon d'installer yaml sur une machine Windows est d'utiliser pip. Exécutez la commande ci-dessous sur votre terminal Windows pour installer yaml,

pip install pyaml (Windows machine)
sudo pip install pyaml (*nix and Mac)

Lors de l'exécution de la commande ci-dessus, l'écran affichera quelque chose comme ci-dessous en fonction de la dernière version actuelle.

Collecting pyaml
Using cached pyaml-17.12.1-py2.py3-none-any.whl
Collecting PyYAML (from pyaml)
Using cached PyYAML-3.12.tar.gz
Installing collected packages: PyYAML, pyaml
Running setup.py install for PyYAML ... done
Successfully installed PyYAML-3.12 pyaml-17.12.1

Pour le tester, allez dans le shell Python et importez le module yaml, importez yaml, si aucune erreur n'est trouvée, alors nous pouvons dire que l'installation est réussie.

Après avoir installé pyaml, regardons le code ci-dessous,

script_yaml1.py

Ci-dessus, nous avons créé trois structures de données différentes, dictionnaire, liste et tuple. Sur chacune des structures, nous faisons yaml.dump. Le point important est la façon dont la sortie est affichée à l'écran.

Production

La sortie du dictionnaire semble propre .ie. valeur clé.

Espace blanc pour séparer différents objets.

La liste est notée par un tiret (-)

Le tuple est d'abord indiqué par !! Python / tuple puis dans le même format que les listes.

Chargement d'un fichier yaml

Alors disons que j'ai un fichier yaml, qui contient,

---
# An employee record
name: Raagvendra Joshi
job: Developer
skill: Oracle
employed: True
foods:
   - Apple
   - Orange
   - Strawberry
   - Mango
languages:
   Oracle: Elite
   power_builder: Elite
   Full Stack Developer: Lame
education:
   4 GCSEs
   3 A-Levels
   MCA in something called com

Maintenant, écrivons un code pour charger ce fichier yaml via la fonction yaml.load. Ci-dessous le code pour le même.

Comme la sortie n'a pas l'air très lisible, je la joliment en utilisant json à la fin. Comparez la sortie que nous avons obtenue et le fichier yaml actuel que nous avons.

Production

L'un des aspects les plus importants du développement logiciel est le débogage. Dans cette section, nous verrons différentes manières de déboguer Python avec un débogueur intégré ou des débogueurs tiers.

PDB - Le débogueur Python

Le module PDB prend en charge la définition des points d'arrêt. Un point d'arrêt est une pause intentionnelle du programme, où vous pouvez obtenir plus d'informations sur l'état du programme.

Pour définir un point d'arrêt, insérez la ligne

pdb.set_trace()

Exemple

pdb_example1.py
import pdb
x = 9
y = 7
pdb.set_trace()
total = x + y
pdb.set_trace()

Nous avons inséré quelques points d'arrêt dans ce programme. Le programme s'arrêtera à chaque point d'arrêt (pdb.set_trace ()). Pour afficher le contenu d'une variable, tapez simplement le nom de la variable.

c:\Python\Python361>Python pdb_example1.py
> c:\Python\Python361\pdb_example1.py(8)<module>()
-> total = x + y
(Pdb) x
9
(Pdb) y
7
(Pdb) total
*** NameError: name 'total' is not defined
(Pdb)

Appuyez sur c ou continuez à exécuter les programmes jusqu'au prochain point d'arrêt.

(Pdb) c
--Return--
> c:\Python\Python361\pdb_example1.py(8)<module>()->None
-> total = x + y
(Pdb) total
16

Finalement, vous devrez déboguer des programmes beaucoup plus gros - des programmes qui utilisent des sous-programmes. Et parfois, le problème que vous essayez de trouver se trouvera dans un sous-programme. Considérez le programme suivant.

import pdb
def squar(x, y):
   out_squared = x^2 + y^2
   return out_squared
if __name__ == "__main__":
   #pdb.set_trace()
   print (squar(4, 5))

Maintenant, exécutez le programme ci-dessus,

c:\Python\Python361>Python pdb_example2.py
> c:\Python\Python361\pdb_example2.py(10)<module>()
-> print (squar(4, 5))
(Pdb)

On peut utiliser ?pour obtenir de l'aide, mais la flèche indique la ligne sur le point d'être exécutée. À ce stade, il est utile de frapper s pours pour entrer dans cette ligne.

(Pdb) s
--Call--
>c:\Python\Python361\pdb_example2.py(3)squar()
-> def squar(x, y):

Ceci est un appel à une fonction. Si vous voulez un aperçu de votre position dans votre code, essayez l -

(Pdb) l
1 import pdb
2
3 def squar(x, y):
4 -> out_squared = x^2 + y^2
5
6 return out_squared
7
8 if __name__ == "__main__":
9 pdb.set_trace()
10 print (squar(4, 5))
[EOF]
(Pdb)

Vous pouvez appuyer sur n pour passer à la ligne suivante. À ce stade, vous êtes dans la méthode out_squared et vous avez accès à la variable déclarée à l'intérieur de la fonction .ie x et y.

(Pdb) x
4
(Pdb) y
5
(Pdb) x^2
6
(Pdb) y^2
7
(Pdb) x**2
16
(Pdb) y**2
25
(Pdb)

Nous pouvons donc voir que l'opérateur ^ n'est pas ce que nous voulions à la place, nous devons utiliser l'opérateur ** pour faire des carrés.

De cette façon, nous pouvons déboguer notre programme dans les fonctions / méthodes.

Enregistrement

Le module de journalisation fait partie de la bibliothèque standard de Python depuis la version 2.3 de Python. Comme il s'agit d'un module intégré, tous les modules Python peuvent participer à la journalisation, de sorte que notre journal d'application puisse inclure votre propre message intégré aux messages du module tiers. Il offre beaucoup de flexibilité et de fonctionnalité.

Avantages de la journalisation

  • Diagnostic logging - Il enregistre les événements liés au fonctionnement de l'application.

  • Audit logging - Il enregistre les événements pour l'analyse commerciale.

Les messages sont écrits et consignés à des niveaux de «gravité» et de minu

  • DEBUG (debug()) - messages de diagnostic pour le développement.

  • INFO (info()) - messages standard de «progression».

  • WARNING (warning()) - détecté un problème non grave.

  • ERROR (error()) - rencontré une erreur, peut-être grave.

  • CRITICAL (critical()) - généralement une erreur fatale (le programme s'arrête).

Regardons ci-dessous le programme simple,

import logging

logging.basicConfig(level=logging.INFO)

logging.debug('this message will be ignored') # This will not print
logging.info('This should be logged') # it'll print
logging.warning('And this, too') # It'll print

Ci-dessus, nous enregistrons les messages au niveau de gravité. Nous importons d'abord le module, appelons basicConfig et définissons le niveau de journalisation. Le niveau que nous avons défini ci-dessus est INFO. Ensuite, nous avons trois instructions différentes: une instruction de débogage, une instruction info et une instruction d'avertissement.

Sortie de logging1.py

INFO:root:This should be logged
WARNING:root:And this, too

Comme l'instruction info est sous l'instruction de débogage, nous ne pouvons pas voir le message de débogage. Pour obtenir également l'instruction de débogage dans le terminal de sortie, tout ce que nous devons changer est le niveau basicConfig.

logging.basicConfig(level = logging.DEBUG)

Et dans la sortie, nous pouvons voir,

DEBUG:root:this message will be ignored
INFO:root:This should be logged
WARNING:root:And this, too

De plus, le comportement par défaut signifie que si nous ne définissons aucun niveau de journalisation, il s'agit d'avertissement. Mettez simplement en commentaire la deuxième ligne du programme ci-dessus et exécutez le code.

#logging.basicConfig(level = logging.DEBUG)

Production

WARNING:root:And this, too

Python intégré au niveau de journalisation sont en fait des entiers.

>>> import logging
>>>
>>> logging.DEBUG
10
>>> logging.CRITICAL
50
>>> logging.WARNING
30
>>> logging.INFO
20
>>> logging.ERROR
40
>>>

Nous pouvons également enregistrer les messages du journal dans le fichier.

logging.basicConfig(level = logging.DEBUG, filename = 'logging.log')

Maintenant, tous les messages du journal iront dans le fichier (logging.log) dans votre répertoire de travail actuel au lieu de l'écran. C'est une bien meilleure approche car elle nous permet de faire une analyse des messages que nous avons reçus.

Nous pouvons également définir l'horodatage avec notre message de journal.

logging.basicConfig(level=logging.DEBUG, format = '%(asctime)s %(levelname)s:%(message)s')

La sortie obtiendra quelque chose comme,

2018-03-08 19:30:00,066 DEBUG:this message will be ignored
2018-03-08 19:30:00,176 INFO:This should be logged
2018-03-08 19:30:00,201 WARNING:And this, too

Benchmarking

L'analyse comparative ou le profilage consiste essentiellement à tester à quelle vitesse votre code s'exécute et où se trouvent les goulots d'étranglement? La principale raison de faire cela est l'optimisation.

timeit

Python est livré avec un module intégré appelé timeit. Vous pouvez l'utiliser pour chronométrer de petits extraits de code. Le module timeit utilise des fonctions de temps spécifiques à la plate-forme afin que vous obteniez les horaires les plus précis possible.

Ainsi, cela nous permet de comparer deux envois de code pris par chacun, puis d'optimiser les scripts pour obtenir de meilleures performances.

Le module timeit possède une interface de ligne de commande, mais il peut également être importé.

Il existe deux manières d'appeler un script. Utilisons d'abord le script, pour cela exécutons le code ci-dessous et voyons la sortie.

import timeit
print ( 'by index: ', timeit.timeit(stmt = "mydict['c']", setup = "mydict = {'a':5, 'b':10, 'c':15}", number = 1000000))
print ( 'by get: ', timeit.timeit(stmt = 'mydict.get("c")', setup = 'mydict = {"a":5, "b":10, "c":15}', number = 1000000))

Production

by index: 0.1809192126703489
by get: 0.6088525265034692

Ci-dessus, nous utilisons deux méthodes différentes .ie par indice et accédons à la valeur de la clé du dictionnaire. Nous exécutons l'instruction 1 million de fois car elle s'exécute trop vite pour de très petites données. Maintenant, nous pouvons voir l'accès à l'index beaucoup plus rapidement que le get. Nous pouvons exécuter le code plusieurs fois et il y aura une légère variation dans l'exécution du temps pour obtenir une meilleure compréhension.

Une autre méthode consiste à exécuter le test ci-dessus dans la ligne de commande. Faisons le,

c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict['c']"
1000000 loops, best of 3: 0.187 usec per loop

c:\Python\Python361>Python -m timeit -n 1000000 -s "mydict = {'a': 5, 'b':10, 'c':15}" "mydict.get('c')"
1000000 loops, best of 3: 0.659 usec per loop

La sortie ci-dessus peut varier en fonction du matériel de votre système et de ce que toutes les applications exécutent actuellement sur votre système.

Ci-dessous, nous pouvons utiliser le module timeit, si nous voulons appeler une fonction. Comme nous pouvons ajouter plusieurs instructions à l'intérieur de la fonction à tester.

import timeit

def testme(this_dict, key):
   return this_dict[key]

print (timeit.timeit("testme(mydict, key)", setup = "from __main__ import testme; mydict = {'a':9, 'b':18, 'c':27}; key = 'c'", number = 1000000))

Production

0.7713474590139164