Vous êtes sur la page 1sur 32

Encapsulation

 Lors de la définition d'une classe, il est possible de


restreindre voire d'interdire l'accès (aux objets des
autres classes) à des attributs ou méthodes des
instances de cette classe.
 Lors de la déclaration d'attributs ou méthodes, on
précise leur utilisation :
 privée : accessible uniquement depuis l’intérieur de la classe.
Règle d’écriture en Python : __att1, __m1(…), …
 public : accessible par toutes les autres classes. Règle
d’écriture en Python : att1, m1(…), …

1
Encapsulation

 Elément essentiel pour l’évolution des applications :


 Tout ce qui est visible peut avoir été utilisé. Le changer peut
casser du code existant.
 Tout ce qui est caché peut encore être changé.
 Encapsulation :
 ne pas permettre l'accès direct à tout dès que l'on a une
référence de l'objet
 masquer les détails d'implémentation au programmeur client
 modifier tout ce qui n'est pas public sans impact pour le
programmeur

2
 Règles d’encapsulation :
 Rendre privés les attributs caractérisant l‘état de l'objet : un
élément qui commence par deux soulignés représente une
information privée.
 Fournir des méthodes publiques permettant d’accéder/
modifier l'attribut (accesseurs/mutateurs)
 Mise en œuvre :
 On commence par définir un attribut normal.
 Si on a besoin de le contrôler, on passe à une propriété :
cette modification ne remet pas en cause le code client qui reste
inchangé

3
Propriétés

 Définition d’une propriété :


class NomClasse :
def __init__(self, val, …)
self.__attr=val

@property
def attr(self):

@attr.setter
def attr(self, valeur):
...
4
 Exemple :
class Fichier : # Mutateur
"""Définition de la classe Fichier""" @nom.setter
def nom(self, nom):
# Constructeur self.__nom=nom
def __init__(self, leNom , ext="txt" ) :
self.__nom = leNom # Autres méthodes
self.__extension=ext def nomEntier(self):
return self.__nom+"."+
# Accesseur self.__extension
@property
def nom(self): #Programme principal
return self.__nom fich= Fichier("MonFichier")
print(fich.nom)
5
Sérialisation d’objets dans des fichiers

 Avec le module pickle, il est possible d’enregistrer un


objet dans un fichier et de le récupérer par la suite.
 Exemple :
import pickle
with open("lesPoints", 'wb') as f :
p= Point(2,3)
pickle.dump(p,f)

with open("lesPoints", 'rb') as f :


p= pickle.load(f)
print(p)
6
Tri d’objets

 Pour trier des séquences, Python propose deux


méthodes :
 La méthode sort() de la classe list. Elle modifie la liste sur
laquelle elle s’applique.
 La fonction de haut niveau sorted(). Elle prend une séquence
comme argument (set, list, tuple, dict) et elle renvoie une
nouvelle séquence triée.
 Exemples :
maListe=["Pomme", "Banane", "Orange","Poire"]
maListe.sort() # maListe vaut ['Banane', 'Orange', 'Poire', 'Pomme']

maListe=[20, 15, 2, 16, 8]


maListeTriee= sorted(maListe) # maListeTriee vaut [2, 8, 15, 16, 20]
7
 Python ne sait pas trier des séquences d’objets de type
défini par l’utilisateur
 Les méthodes list.sort() et sorted() ont un pramètre
optionnel appelé key de type fonction.
 La fonction à passer en argument prend un élément de
la liste et renvoie ce sur quoi doit ce faire le tri.
 Exemples :
fruits=[("Pommes", 1.800, 50), ("Banane", 4.000, 25), ("Orange", 2.500, 30)]

fruits.sort(key= lambda elment: elment[1])

# fruits vaut [('Pommes', 1.8, 50), ('Orange', 2.5, 30), ('Banane', 4.0, 25)]

8
 Exemples (suite) :
class Etudiant :
def __init__(self, nom, age, moyenne):
self.nom=nom
self.age=age
self.moyenne=moyenne
def __repr__(self) :
return self.nom

e1= Etudiant("Ali", 20, 13.40)


e2= Etudiant("Ahmed", 21,12.50)
e3= Etudiant("Salma", 20, 13.00)
liste=[e1, e2, e3]
liste.sort(key= lambda e : e.age, reverse=True)
print(liste) # [e2,e1,e3]

9
 Les fonctions lambda ne sont pas le meilleur choix au
niveau rapidité, si l’on veut trier une liste contenant
beaucoup d’objets
 Le module operator propose les
fonctions itemgetter() et attrgetter() qui peuvent être
très utiles en tant que fonction clés, si l’on veut trier une
liste de tuples ou d'objets selon un attribut ;
 Exemple :
from operator import itemgetter
inventory = [(‘pomme', 3), ('banane', 2), ('orange', 1)]
sorted(inventory, key=itemgetter(0))
10
 Exemple :
from operator import attrgetter
e1= Etudiant("Ali", 20, 13.00)
e2= Etudiant("Ahmed", 21,12.50)
e3= Etudiant("Salma", 22, 13.00)
e4= Etudiant("Kamel", 20, 13.00)
liste=[e1, e2, e3, e4]
listeTriee= sorted(liste, key=attrgetter("moyenne", "age"), reverse=True)
print (listeTriee) # [Salma, Ali, Kamel, Ahmed]

11
Héritage

 Le principe d’héritage stipule que les caractéristiques


des classes supérieures sont héritées par les classes
dérivées.
 Sa mise en œuvre consiste à mettre les connaissances
les plus générales en commun dans des classes qui
sont ensuite spécialisées par la définition de sous-
classes contenant des connaissances de plus en plus
spécifiques.

12
Héritage

 La spécialisation d'une classe peut être réalisée selon


deux techniques :
 L'enrichissement : la sous-classe est dotée de nouvelle(s)
méthode(s) et/ou de nouveau(x) attribut(s) ;
 La redéfinition : une (ou plusieurs) méthode et/ou un attribut
hérité est redéfini.

13
Héritage

class Fichier : class FichierBinaire (Fichier) :


"""Définition de la classe """Définition de la classe
Fichier""" FichierBinaire"""
def __init__(self):
def __init__(self, enc):
self.__taille=0 Fichier.__init__(self)
self.__encodage=enc
def setTaille(self, taille) self.__taille= "0"
self.__taille=taille
def imprimer(self):
pass
def ouvrir(self):
print("Ouvrir le fichier") def ouvrir(self) :
print("Ouvrir fichier binaire")
14
Héritage et polymorphisme

 L’héritage multiple consiste à faire hériter une classe de


plusieurs superclasses.
 L'idée est de regrouper au sein d'une seule et même
classe les attributs et méthodes de plusieurs classes.
 Python permet l’héritage multiple
 Le polymorphisme signifie qu’à un même service
(d’une classe de base peuvent correspondre, dans les
classes dérivées, des méthodes différentes. Chaque
classe dérivée définit la forme (-morphe) sous laquelle
elle remplit le service (méthode).

15
Héritage et attributs protégés

 Les attributs protégés sont les attributs d’une classe de


base qui ne sont visibles que des sous-classes. Règle
d’écriture en Python : _att1, _att2
 En python, les attributs et méthodes protégées sont
accessibles normalement ; le préfixe a pour seul
objectif d'informer sur leur nature

16
Exceptions

 Le principe des exceptions consiste à séparer la


détection d'une anomalie de son traitement.
 Une exception est levée pour signaler une anomalie
lors de l'exécution d'une instruction.
 Exemples d’exceptions en Python
 10 / 0
ZeroDivisionError: division by zero

 int('spam')
ValueError: invalid literal for int() with
base 10: 'spam'

17
Exceptions

 d = { 'poires' : 5, 'pommes' : 7 }
d['oranges']
KeyError: 'oranges'

 IndexError : Accès à un indice inexistant


 TypeError : type d'argument incorrect
 OSError : erreur provoquée par un appel système
 NotImplementedError : erreur levée quand une méthode ne
possède pas d’implémentation
 ValueError: invalid literal for int() with base 10: 'spam‘
 …

18
Exceptions

 Si une exception est levée dans une méthode, alors


l'exécution de la méthode s'arrête et on retourne
l'exception à l'appelant
 L'appelant peut traiter l'anomalie génératrice de
l'exception si l'appel est fait dans un bloc try/except
try :
instruction1
instruction2
...
except Exception :
actions
19
Levée d’une exception

 On peut forcer la levée d'une exception en utilisant


l'instruction raise
 Exemple :

if a<0 :
raise Exception

20
Exceptions utilisateur

 Les exceptions sont des objets.


 On peut définir de nouvelles exceptions en spécialisant
la classe Exception
 On utilise les exceptions afin de vérifier la bonne
utilisation des méthodes.
 Exemple :
class ListeVide(Exception): else:
pass p=1
for i in liste :
def produit(liste:list)-> float: if i!=0 :
if not liste: p*=i
raise ListeVide return p
21
Traitement des exceptions

 Chaque type d'exception peut avoir un traitement


différent
try :
instruction1
instruction2
...
except ExceptionType1 :
actions
except ExceptionType2 :
actions
finally :
actions à exécuter dans tous les cas (sauf sortie du programme)
22
Exceptions et objets

 Exemple : vérifier que les paramètres d'entrée d'une


méthode ont les bons types et les bonnes valeurs
class NombreNegatif (Exception): #main
def __init__(self,message): try :
self.message=message racineCarree(-1)
def racineCarree(n): except NombreNegatif as e :
if (n<0) : print(e.message)
raise NombreNegatif("Pas de finally :
racine pour les nombres négatifs") print("C'est terminé")
else : print ("au revoir")
print(sqrt(n))

23
Gestion des exceptions

 Exemple :

while True:
s = input('Entrez un entier : ')
try:
n = int(s)
print(n + 1)
break
except ValueError :
print("{} n'est pas un entier !".format(s))

24
Assertions

 Les assertions sont un moyen de s’assurer, avant de


continuer, qu’une condition est respectée.
 En général, on les utilise dans des blocs try … except
 Syntaxe :
assert test
 Si le test renvoie True, l’exécution se poursuit
normalement. Sinon, une exception AssertionError est
levée

25
 Exemple
annee = input( "Saisissez une année : ")
try :
annee= int(annee)
assert annee>0
except ValueError :
print("Donnez un nombre!")
except AssertionError :
print("Donnez un nombre positif !")

26
Classes abstraites

 Une classe abstraite est une classe qui ne peut pas


être instanciée
 Les classes abstraite renforcent l'extensibilité des
programmes en factorisant des attributs et des
méthodes communs à différentes classes.
 Pour obliger une classe fille d'une classe abstraite
d'implémenter les méthodes abstraites, on utilise le
module abc (Abstract Base Class) qui permet de
déclarer explicitement qu'une classe/ou une méthode
est abstraite.

27
 Exemples :
from abc import ABC
class ObjetGeometrique(ABC):
@abc.abstractmethod
def surface (self):
pass

geo= ObjetGeometrique()

TypeError : Can't instantiate abstract class ObjetGeometrique with abstract


methods surface

28
 Exemple (suite) :
class Carre(ObjetGeometrique):
def __init__(self, cote):
self.cote=cote
def surface (self):
return cote**2

c= Carre(5)
print(c.surface())

29
Itérateurs

 La boucle
for i in obj :
permet de balayer tout objet obj itérable, c’est-à-dire
définissant la méthode __iter__(self)
 __iter__(self ) doit renvoyer un itérateur définissant la
méthode __next__(self)
 __next__(self) renvoie un objet (la valeur prise par i) et
modifie l’état de l’itérateur pour passer à l’élément
suivant.
 L’exception StopIteration est levée si l’appel à
__next__( ) est impossible.
30
 La boucle for est donc équivalente à:

it = obj.__iter__( )
try:
while True:
i = it.__next__()
...
except StopIteration:
pass

31
 Exemple :

class UpTo: else:


def __init__(self,n): self.i = self.i + 1
self.n = n return self.i
self.i = 0 for i in UpTo(5):
def __iter__(self): print (i) # affiche 1,2,...,5
return self print(list(UpTo(5))) # [1, 2, 3, 4, 5]

def __next__(self):
if self.i == self.n:
raise StopIteration
32

Vous aimerez peut-être aussi