TP3,14 : programmation orientée objet en Python

Classes, méthodes, constructeurs, opérateurs.

Introduction

Dans le TD-1, nous avons manipulé des fichiers ainsi que leur taille.


Peut-être avez-vous programmé une liste de couples, du genre [(fichier1, taille1), (fichier2, taille2), (fichier3, taille3), …]


Nous allons voir comment utiliser la programmation objet pour implémenter la même chose de manière plus propre.


# on définit une classe « vide »
class fichier:
    pass
# on crée f1, une <em>instance</em> de cette classe
f1 = fichier()
f1.nom = "toto.py"
f1.taille = os.stat(f1.nom).st_size
print "le fichier %s fait %d octets"%(f1.nom, f1.taille)

Intégrons ce code dans la classe :


class fichier:
    def __init__(self, nom):
        self.nom = nom
        self.taille = os.stat(self.nom).st_size
    def affiche(self):
        print "le fichier %s fait %d octets"%(self.nom, self.taille)

Notons que les fonctions définies à l’intérieur de la classe s’appelles des méthodes, et qu’elles prennent toujours comme premier argument l’instance sur laquelle elles travaillent. Par convention, on appelle cet argument « self » mais ça n’est pas obligatoire.


On peut accéder aux champs d’une instance ou à ses méthodes avec la syntaxe moninstance.monchamp ou encore moninstance.maméthode(arguments…) tout simplement. Les affectations sont possibles depuis l’extérieur de la classe.


Héritage


Petit exemple :


class point:
    def __init__(self, x=0, y=0):
        self.x, self.y = x, y
    def translation(self, dx, dy):
        self.x += dx
        self.y += dy
    def distance(self, autre_point):
        norme = 0
        norme += (self.x-autre_point.x)**2
        norme += (self.y-autre_point.y)**2
        return math.sqrt(norme)
class pointcouleur(point):
    def __init__(self, x=0, y=0, c="noir"):
        point.__init__(self, x, y)
        self.couleur = c

 


Opérateurs


Il y a un ensemble de méthodes spécialies, dont les noms sont entourés d’un double underscore.


Citons particulièrement :


  • init, le « constructeur », qui est appelé lorsqu’on veut créer une nouvelle instance de la classe ;
  • str, qui est appelé lorsqu’on fait str(x) ou encore “print x” ou encore “%s”%x ;
  • repr, qui est appelé lorsqu’on fait repr(x) ou quand on affiche l’instance dans l’interpréteur ;
  • add, sub, mul, div, qui correspondent aux 4 opérations classiques ;
  • eq, le, lt, ge, gt, qui correspondent respectivement aux comparaisons ==, <=, <, =>, > ;
  • etc.

Consultez « dir(0) » pour avoir une petite liste !


 


Exercices



Écrire une classe polynom répondant aux spécifications suivantes :


  • on veut pouvoir construire un polynôme en spécifiant les coefficients
    comme arguments du constructeur, de la plus haute puissance à la plus
    petite : p1=polynom(1,0,-1) # X^2 – 1

  • on veut pouvoir évaluer le polynôme en une valeur X donnée (en l’appelant comme une fonction) : p1(4) # =15
  • on veut pouvoir utiliser la fonction len pour connaître le nombre de coefficiens (attention il ne s’agit pas du degré, mais du degré+1) : len(p1) # =3

  • on veut pouvoir récupérer le i-ème coefficient en utilisant le polynôme comme un tableau : p10 # =-1

  • si le constructeur est appelé avec un unique argument et que cet
    argument est une liste ou un couple, on souhaite utiliser cet argument
    comme liste des coefficients, où le i-ème élément de la liste
    correspond à la i-ème puissance du polynôme : polynom([1,2,4,1]) # X^3 + 4X^2 + 2X – 1

  • on souhaite additionner et soustraireles polynômes entre eux, avec les opérateurs usuels : p1+polynom(1,0,1) # = polynom(2,0,0)

  • on souhaite pouvoir utiliser les fonctions repr et str sur ces polynômes ; str réalisant un affichage “joli” par exemple X4 – 3×3 + 2X – 1 (en évitant les formes “lourdes” comme 1×4 par exemple, ou 2×1, ou encore 1×0…) et repr faisant un affichage du style ’polynom(1,0,-1)’

  • on souhaite additionner, et soustraire et multiplier les polynômes avec des nombres entiers et flottants, à gauche et aussi à droite (utiliser les opérateurs avec priorité à droite radd et compagnie)

  • on souhaite pouvoir élever le degré d’un polynôme avec l’opérateur décalage à gauche : (2*X^3 + 1) << 4 = 2*X^7 + X^4

  • implémenter ensuite l’opérateur de multiplication de deux polynômes entre eux.

  • proposer un opérateur pour la dérivée des polynômes (et l’implémenter)

Boss de fin de niveau



Résoudre, dans l’ordre que vous voudrez, et en proposant les restrictions que vous jugerez nécessaires, les problèmes suivants :



  • écrire une fonction pour trouver les éventuelles solutions de l’équation P(X)=0 pour un polynôme donné

  • écrire une fonction réalisant l’affichage graphique la courbe Y=P(X)




Soyez créatifs pour ces deux dernières questions ; tous les coups sont permis :-)


Annexe – exemple d’utilisation


def test():
   &nbsp;p1=polynom(1,0,1)<tt>
</tt>    p2=polynom(1,-2,2,1)
    p3=polynom(0,-1,0,1)
    print p1, p2, p3<tt>
</tt>    print p1+p2, p1+p3
    print p1-p2, p1-p3
    print p1*p2