IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ Python

FAQ PythonConsultez toutes les FAQ

Nombre d'auteurs : 11, nombre de questions : 188, dernière mise à jour : 14 juin 2021 

 
OuvrirSommaireProgrammation objet

Vous pouvez sauvegarder de manière très simples dans des fichiers des objets python basiques ou même des objets que vous auriez vous-mêmes définis.
S'il s'agit de nombres (int, float, ...), chaînes de caractères, conteneurs (tuples, listes, dictionnaires) contenant uniquement des objets de types élémentaires, vous pouvez utiliser le module marshal. Sinon, s'il s'agit d'instances de classe que vous avez vous-mêmes définis, utilisez le module pickle ou cPickle (qui est beaucoup plus rapide que pickle)

La fonction dump(value, file)value est l'objet élémentaire à sauvegarder et file est un fichier ouvert en écriture.
La focntion load(fileobj) permet de lire un fichier et retourne l'objet enregistré; fileobj étant un fichier ouvert en lecture.

 
Sélectionnez
import marshal
import cPickle

dico = {}
dico['toto'] = [23,'53453',{'a':5}]
marshal.dump(dico, open("mondico", 'wb')) ## Sauvegarde du dictionnaire 
print marshal.load(open("mondico", "rb")) ## Rechargement du dictionnaire

class toto:
    def __init__(self):
        self.x = 5
tutu = toto()
cPickle.dump(tutu, open("toto2", "wb"))  ## Sauvegarde de l'objet tutu
print cPickle.load(open("toto2")).x      ## Rechargement de l'objet tutu
Créé le 13 avril 2006  par Guigui_

Vous pouvez avoir besoin de travailler sur des objets contenant directement le contenu d'images ou bien de transférer des objets devant travailler sur des images. Vous devez tout d'abord récupérer et installer la bibliothèque Pil. Au lieu de devoir ainsi fournir un fichier contenant l'objet et chacune des images dans des fichier séparés ou dans un fichier .zip, vous pouvez alors décider d'utiliser un unique fichier qui peut ainsi faciliter la procédure. En revanche, si vous travaillez avec des images compressées, le fichier que nous allons créer sera beaucoup plus gros que l'ensemble des fichiers images le constituant.
Pour cela, il suffit tout d'abord d'ouvrir chaque image en tant fichier binaire grâce à la commande open et le paramètre 'rb' et de les conserver dans une variable ou un autre conteneur (comme une liste ou un dictionnaire).
la méthode seek(0) vous permet de vous placer au début du fichier et la méthode read() de lire le contenu entier du fichier ouvert.

Sauvegarde dans un fichier une instance Python contenant 2 images
Sélectionnez
import cPickle
img1 = open('first.jpg', 'rb')
img1.seek(0)
w1 = img1.read()
img1.close()
img2 = open('second.jpg', 'rb')
img2.seek(0)
w2 = img2.read()
img2.close()
dic = {'img1' : w1, 'img2': w2}
cPickle.dump(dic, open("monfichier", "wb"))

Une fois que vous avez récupérer le fichier créé avec cPickle, vous pouvez récupérer en connaissant la structure du fichier les 2 images transmises. Pour cela, on va utiliser le module cStringIO qui permet de lire et de créer des fichiers en mémoire. Par la méthode write, nous allons écrire le contenu de nos variables, se repositionner avec seek(0) au début du fichier. Enfin, nous allon récréer une image grâce à Pil et la fonction Image.open.

Recréation des 2 images à partir d'une instance créée avec cPickle
Sélectionnez
import Image, cPickle, cStringIO
monobjet = cPickle.load(open("monfichier"))
img1 = cStringIO.StringIO()
img1.write(monobjet['img1'])
img1.seek(0)
im1 = Image.open(img1)
im1.save('first.jpg')
img2 = cStringIO.StringIO()
img2.write(monobjet['img2'])
img2.seek(0)
im2 = Image.open(img2)
im2.save('second.jpg')
Créé le 23 octobre 2006  par Guigui_

Vous pouvez récupérer le nom de la classe d'un objet en appliquant à cet objet l'attribut .__class__.__name__

 
Sélectionnez
>>> a = 5
>>> a.__class__.__name__
'int'
>>> class toto: pass

>>> b = toto()
>>> b.__class__.__name__
'toto'
Créé le 13 avril 2006  par Guigui_

Les objets immuables que l'on utilise traditionnellement sont les nombres et les chaînes de caractères. Pour ces objets, on ne peut effectuer un héritage traditionnelle qui utilise la méthode __init__ qui n'a aucune influence sur la valeur retournée par le constructeur dans ce cas-là. Vous devez alors utiliser la méthode __new__(...) comme sur l'exemple suivant. Si vous redéfinissez ensuite des fonctions que la classe parente possède déjà, n'oubliez pas d'utiliser si nécessaire la fonction super(cls, obj) qui permet d'appeler les fonctions de la classe mère sous peine parfois d'obtenir des erreurs de récursion infinie. Etudiez ainsi l'exemple suivant où la classe angle dérive de la classe int en redéfinissant quelques fonctions basiques.

Construction d'une classe angle qui donne l'angle principale entre 0 et 360°
Sélectionnez
class angle(int):
    def __new__(self, n):
    	## On retourne l'angle principale dans l'intervalle [0;360]
        return int.__new__(self, n % 360)
    def __sub__(self, n):
    	## On calcule la différence de 2 angles en retournant l'angle principal
        return angle(super(angle, self).__sub__(n))
    def __add__(self, n):
    	## On calcule la somme de 2 angles en retournant l'angle principal    
        return angle(super(angle, self).__add__(n))

A = angle(540)
B  = angle(- 460)
print A, B, type(A), type(B)  ## 180 260 <class '__main__.angle'> <class '__main__.angle'>
print A - B, type(A - B)	  ## 280 <class '__main__.angle'>
print A + B, type(A - B)	  ## 80 <class '__main__.angle'>
Créé le 29 novembre 2006  par Guigui_

En Python, on peut surcharger tous les opérateurs. L'ensemble de ces opérateurs est identique à ceux que l'on retrouve dans le module operator. Ces opérateurs se redéfinissent donc dans une classe de la manière suivante def __operateur__(self, ...): ...
Dans l'exemple suivant, nous allons créer une classe Vecteur et définir les opérations habituelles sur un vecteur

 
Sélectionnez
# -*- coding: cp1252 -*-
import math

class Vector:
    def __init__(self, x=0, y=0):
        self.x=x
        self.y=y
    def __eq__(self, vB): return (self.x==vB.x) and (self.y==vB.y)    ## test l'égalité de 2 vecteurs        
    def __add__(self, vB):  return Vector(self.x+vB.x,self.y+vB.y)  ## retourne le vecteur somme
    def __sub__(self, vB):  return Vector(self.x-vB.x,self.y-vB.y) ## retourne le vecteur différence
    def __mul__(self, c):
        if isinstance(c,Vector): return  self.x*c.x+self.y*c.y ## retourne le produit scalaire
        else: return Vector(c*self.x,c*self.y) ## retourne le vecteur multiplé par un scalaire
    def __div__(self, c): return Vector(self.x/c, self.y/c) ## retourne le vecteur ayant subi une division scalaire
    def __abs__(self): return math.hypot(self.x, self.y) ## retourne la norme2 du vecteur
    def __str__(self): return '('+str(self.x)+','+str(self.y)+')' ## retourne la réprésentation du vecteur sous forme d'une chaîne

>>> a = Vector(4,5)
>>> b = Vector(6,7)
>>> print a==b
False
>>> print a+b
(10,12)
>>> print a-b
(-2,-2)
>>> print a*b
59
>>> print abs(a)
6.40312423743
Créé le 19 septembre 2006  par Guigui_

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005-2009 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.