Outils pour utilisateurs

Outils du site


sauve_recup_objets

Warning: Undefined array key -1 in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/html.php on line 1458

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
sauve_recup_objets [2008/04/12 08:45]
tyrtamos
sauve_recup_objets [2009/10/06 08:57] (Version actuelle)
tyrtamos
Ligne 1: Ligne 1:
 ====== Sauvegarder et recharger des objets Python de base ====== ====== Sauvegarder et recharger des objets Python de base ======
 +
 +(modifié le 6/10/2009: ajout d'une 3ème méthode)
  
 Quelques essais de sauvegarde et de récupération d'objets Python m'ont montré que cela n'était pas aussi évident que cela.  Quelques essais de sauvegarde et de récupération d'objets Python m'ont montré que cela n'était pas aussi évident que cela. 
Ligne 44: Ligne 46:
 import shelve import shelve
  
 +# sauvegarde des objets
 d = shelve.open('historiquedbm') d = shelve.open('historiquedbm')
- 
-# sauvegarde des objets 
 d['L0'] = L0 d['L0'] = L0
 d['L1'] = L1 d['L1'] = L1
Ligne 59: Ligne 60:
 d.close() d.close()
  
 +# récupération des objets sauvegardés
 d = shelve.open('historiquedbm') d = shelve.open('historiquedbm')
- 
-# récupération des objets sauvegardés 
 R0 = d['L0'] R0 = d['L0']
 R1 = d['L1'] R1 = d['L1']
Ligne 90: Ligne 90:
 Résultat de l'exécution: Résultat de l'exécution:
  
-<code python>+<code>
 objets a sauvegarder: objets a sauvegarder:
 True <type 'bool'> True <type 'bool'>
Ligne 201: Ligne 201:
 Ce qui donne comme résultat d'exécution: Ce qui donne comme résultat d'exécution:
  
-<code python>+<code>
 objets a sauvegarder: objets a sauvegarder:
 True <type 'bool'> True <type 'bool'>
Ligne 228: Ligne 228:
  
 Vous voyez que les objets récupérés sont identiques en valeur et en type avec les données de départ. Il sont aussi identiques aux résultats de shelve, à part que le fichier de sauvegarde est consultable et éditable avec un simple éditeur de texte. Vous voyez que les objets récupérés sont identiques en valeur et en type avec les données de départ. Il sont aussi identiques aux résultats de shelve, à part que le fichier de sauvegarde est consultable et éditable avec un simple éditeur de texte.
 +
 +===== Recharge, manipulation et sauvegarde d'un dictionnaire de variables =====
 +
 +On va utiliser la méthode précédente, mais en imitant la méthode shelve. Pour cela, on va créer une nouvelle classe.
 +
 +Cette classe, appelée ici Dicovar, est dérivée par héritage d'un type dict. On pourra donc bénéficier de toutes les méthodes du type dict (dictionnaire).
 +
 +Comme pour la méthode précédente, ce n'est valable que pour les types de données de base: int, long, float, complex, str, unicode, tuple, list, dict. En fait, ce sont tous les types dont on peut stocker la valeur avec repr() et dont on peut la retrouver avec eval(). Ce n'est pas le cas, par exemple, avec un type fonction: pour la fonction toto(), repr(toto) donnera quelque chose comme <function toto at 0x02A72CF0> qui donnera une erreur dans eval.
 +
 +A quoi peut bien servir un code pour gérer un dictionnaire de variables? Voici un exemple: je voulais créer une calculatrice qui exploite des variables dans les expressions. Mais il s'agissait de variables de calcul, et non de variables du code de la calculatrice elle-même. Or, la fonction eval a deux paramètres optionnels intéressants: on peut ajouter un dictionnaire de variables globales et éventuellement un dictionnaire de variables locales . Prenons un exemple simplifié:
 +
 +<code python>
 +D = {'A':2, 'B':3}
 +print eval("A*B", D)
 +6
 +</code> 
 +
 +Vous voyez que le dictionnaire D a été exploité dans le calcul par eval! On pourra donc, avec le code qui suit, non seulement assurer un suivi des variables d'un calcul d'expression à l'autre, mais aussi d'une session de calcul à l'autre (grâce au stockage sur disque).
 +
 +Voilà le code:
 +
 +<code python>
 +import os
 +
 +class Dicovar(dict):
 +    def __init__(self, nf):
 +        self.nf = nf
 +        try:
 +            f = open(nf, 'r')
 +            dict.__init__(self, eval(f.readline().rstrip('\r\n')))
 +            f.close()
 +        except:
 +            dict.__init__(self, {})
 +
 +    def enregistre(self):
 +        f =  open(self.nf, 'w')
 +        f.write(repr(self) + os.linesep)
 +        f.close()
 +</code>
 +
 +L'utilisation est très simple. 
 +
 +A l'instanciation de la classe, il y a tentative de lecture du fichier dont on donne le nom en paramètre. 
 +
 +  * En cas d'erreur, c'est que le fichier n'existe pas, et on initialise le dictionnaire avec un dictionnaire vide. 
 +
 +  * S'il n'y a pas d'erreur, le fichier donné devrait contenir un dictionnaire de variable, et on le lit pour initialiser le dictionnaire en mémoire.
 +
 +A la fin, pour enregistrer le dictionnaire en cours sur disque, il suffit d'appeler la méthode enregistre(), ce qui fait qu'on pourra le retrouver à l'identique la prochaine fois.
 +
 +Entre ces deux opérations (initialisation et enregistrement), on a droit à toutes les fonctions du type dictionnaire.
 +
 +Exemples:
 +
 +<code python>
 +# objets a sauvegarder sur disque et à recuperer
 +L0=True
 +L1=123
 +L2=456L
 +L3=1.789e5
 +L4=complex(1,2)
 +L5="ABC"
 +L6=u"DEF"
 +L7=[L0,L1,L2,L3,L4,L5,L6]
 +L8=(L0,L1,L2,L3,L4,L5,L6)
 +L9={'L0':L0,'L1':L1,'L2':L2,'L3':L3,'L4':L4,'L5':L5,'L6':L6}
 + 
 +print "objets a sauvegarder:" 
 +print L0, type(L0)
 +print L1, type(L1)
 +print L2, type(L2)
 +print L3, type(L3)
 +print L4, type(L4)
 +print L5, type(L5)
 +print L6, type(L6)
 +print L7, type(L7)
 +print L8, type(L8)
 +print L9, type(L9)
 +print
 + 
 +#########################################################################
 +# Sauvegarde et récupération d'objets Python avec la classe Dicovar
 + 
 +# sauvegarde des objets
 +d = Dicovar('testdicovar.txt')
 +d['L0'] = L0
 +d['L1'] = L1
 +d['L2'] = L2
 +d['L3'] = L3
 +d['L4'] = L4
 +d['L5'] = L5
 +d['L6'] = L6
 +d['L7'] = L7
 +d['L8'] = L8
 +d['L9'] = L9
 +d.enregistre()
 + 
 +# récupération des objets sauvegardés
 +d = Dicovar('testdicovar.txt')
 +R0 = d['L0']
 +R1 = d['L1']
 +R2 = d['L2']
 +R3 = d['L3']
 +R4 = d['L4']
 +R5 = d['L5']
 +R6 = d['L6']
 +R7 = d['L7']
 +R8 = d['L8']
 +R9 = d['L9']
 +d.enregistre()
 + 
 +print "objets recuperes par Dicovar" 
 +print R0, type(R0)
 +print R1, type(R1)
 +print R2, type(R2)
 +print R3, type(R3)
 +print R4, type(R4)
 +print R5, type(R5)
 +print R6, type(R6)
 +print R7, type(R7)
 +print R8, type(R8)
 +print R9, type(R9)
 +print
 +</code>
 +
 +Ce qui affiche:
 +
 +<code>
 +objets a sauvegarder:
 +True <type 'bool'>
 +123 <type 'int'>
 +456 <type 'long'>
 +178900.0 <type 'float'>
 +(1+2j) <type 'complex'>
 +ABC <type 'str'>
 +DEF <type 'unicode'>
 +[True, 123, 456L, 178900.0, (1+2j), 'ABC', u'DEF'] <type 'list'>
 +(True, 123, 456L, 178900.0, (1+2j), 'ABC', u'DEF') <type 'tuple'>
 +{'L6': u'DEF', 'L4': (1+2j), 'L5': 'ABC', 'L2': 456L, 'L3': 178900.0, 'L0': True, 'L1': 123} <type 'dict'>
 +
 +objets recuperes par Dicovar
 +True <type 'bool'>
 +123 <type 'int'>
 +456 <type 'long'>
 +178900.0 <type 'float'>
 +(1+2j) <type 'complex'>
 +ABC <type 'str'>
 +DEF <type 'unicode'>
 +[True, 123, 456L, 178900.0, (1+2j), 'ABC', u'DEF'] <type 'list'>
 +(True, 123, 456L, 178900.0, (1+2j), 'ABC', u'DEF') <type 'tuple'>
 +{'L6': u'DEF', 'L4': (1+2j), 'L5': 'ABC', 'L2': 456L, 'L3': 178900.0, 'L0': True, 'L1': 123} <type 'dict'>
 +</code>
 +
 +Comme dans les méthodes précédentes, on peut vérifier que les données sont récupérées en valeur et en type.
 +
 +Petits compléments: comme grâce à l'héritage on peut utiliser les méthodes du type dictionnaire:
 +
 +Remise à "dictionnaire vide" du fichier:
 +
 +<code python>
 +s = Dicovar('testdicovar.txt')
 +s.clear()
 +s.enregistre()
 +</code>
 +
 +Réinitialisation en cours d'exécution avec un autre dictionnaire de variables (appelé ici D):
 +
 +<code python>
 +s = Dicovar('testdicovar.txt')
 +s.clear()
 +s.update(D)
 +s.enregistre()
 +</code>
 +
 +Etc...
 +
 +Amusez-vous bien!
 +  
  
 <html> <html>
sauve_recup_objets.txt · Dernière modification: 2009/10/06 08:57 de tyrtamos