🎧 New: AI-Generated Podcasts Turn your study notes into engaging audio conversations. Learn more

C06 - [FR] Classes et Objets.pdf

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Full Transcript

Classes et Objets en Python Jean-Sébastien Monzani - Mauro Cherubini - Alexandre Métrailler Éléments de programmation ▸ C06 ▸ Printemps 2024 1 Objectifs de ce chapitre A.18 - objets en pyt...

Classes et Objets en Python Jean-Sébastien Monzani - Mauro Cherubini - Alexandre Métrailler Éléments de programmation ▸ C06 ▸ Printemps 2024 1 Objectifs de ce chapitre A.18 - objets en python, classes d’objets, attributs et liens A.19 - méthodes: fonctions attachées aux classes A.20 - diagrammes de classes UML pour des classes python A.21 - les méthodes et classes vus dans les leçons précédentes 2 Activités obligatoires avant le cours C06.1 - Objects, classes and attributes 10m C06.2 - Constructors 12m C06.3 - Methods 8m C06.4 - UML schemas 8m C06.5 - Les classes et les objets dans les leçons précédentes 4m 3 15m C06.1 - Objects, classes and attributes 4 Classe Instance de l’objet source 5 La classe réunit des données et leurs opérations class C: Les données stockées dans la classe sont appelées des attributs. def __init__(self,...) On les initialise dans un constructeur définition des attributs avec : __init__(self,...) def ma_methode(self,...) Les opérations / fonctions qu'on peut appliquer sur ces données sont définition des méthodes appelées des méthodes Créer des objets, donner une valeur à un objet Dans les cinq premières leçons sur le langage Python, nous avons manipulé des variables et des valeurs de différents types: des valeurs élémentaires contenant un nombre, ou une chaîne de caractère, ou éventuellement une valeur logique True/False, des listes de ces valeurs élémentaires nous permettant de mettre toute une collection derrière un nom, chaque valeur indicée par un nombre entier, des dictionnaires permettant de construire des collections où on peut accéder à chaque valeur par une clé (pouvant être un mot, ou une chaîne de caractères quelconques, et pas seulement un nombre entier entre 0 et n-1), des tuples qui sont des sortes de listes immuables (inchangeables). 7 Créer des objets, donner une valeur à un objet En fait, le langage python nous permet de construire et définir toutes sortes de types de données. Cela se fait en déclarant d'abord une classe de valeurs (avec le mot réservé class). Puis en créant des valeurs qu'on appelle objets de cette classe. Ce texte est facultatif : c'est la documentation de la classe class Personne: "Chaque objet de cette classe sera une personne" pass Note: La ligne pass est là pour signaler que dans ce cas très simple, nous n'avons rien de plus à préciser à propos de la classe Personne. Ce qui est très rare, habituellement nous aurons des instructions à cet endroit pour préciser un peu ce qu'est et comment se comporte un objet de la classe Personne. 8 Attributs (ou variables) d’instance Personne() class Personne:.nom.prenom.dateNaiss.sport nom prenom date de naissance sport 9 Comment écrire une classe en Python class Personne: "Chaque objet de cette classe sera une personne" constructeur def __init__(self, nom, prenom, dateNaiss, sport): self.nom = nom self.prenom = prenom conversion de attributs self.dateNaiss = int(dateNaiss) type (casting) self.sport = sport self.age = self.calculateAge() def calculateAge(self): méthode interne return (2024 - self.dateNaiss) 10 Créer des objets Ensuite nous pouvons commencer à créer des objets de type Personne en écrivant des expressions de la forme: p = Personne( On met ici les paramètres du constructeur ) on peut manipuler les attributs (des propriétés) avec la notation objet.attribut. Exemples: gerard = Personne('Manvussa', 'Gérard', 1960, 'randonnée') print(gerard.nom) --> 'Manvussa' print(gerard.prenom) --> 'Gérard' print(gerard.dateNaiss) --> 1960 print(gerard.sport) --> 'randonnée' sarah = Personne('Aykassé', 'Sarah Kate', 1988, 'tennis') print(sarah.nom) --> 'Aykassé' print(sarah.prenom) --> 'Sarah Kate' print(sarah.dateNaiss) --> 1988 print(sarah.sport) --> 'tennis' 11 Assignation de valeurs et accès aux attributs Cette notation est utilisable dans toutes les expressions où on souhaite mentionner l'une au l'autre des propriétés (des attributs) de nos objets: ageSarah = 2024 - sarah.dateNaiss print(ageSarah) if sarah.sport == gerard.sport : print('Ces deux-là font le même sport!') sarah.sport = 'athlétisme' sarah.niveauSportif = 'national' 12 Imbrication d’objets les uns dans les autres Les valeurs que prennent les attributs des objets peuvent Personne être quelconques. Donc la valeur d'un attribut peut être un dateNaiss 2002 autre objet, ou plus précisément la référence à un autre nom Aztakès objet: prenom Hélène helene = Personne('Aztakès', 'Hélène', 2002, 'pingpong') helene.fille = sarah sport pingpong fille sarah L'attribut fille entre les objets helene et sarah crée une imbrication des objets entre eux. On peut par exemple évoquer le sport de la fille d'hélène avec l'expression: dateNaiss 1988 nom Aykassé prenom Sarah Kate sport athlétisme 13 Imbrication = références entre objets Les attributs d'objets, comme les variables, référencent leurs valeurs respectives, ils ne contiennent pas vraiment ces valeurs, comme des boîtes contiennent des objets. La bonne image est la variable-tentacule: elle lie un nom de variable ou d'attribut avec une valeur. Si on ajoute à notre code l’instruction: gerard.fille = sarah alors on crée une situation semblable à celle-ci: gerard.fille.sport == helene.fille.sport 14 Préparez et posez vos questions! 15 15m C06.2 - Constructeurs 16 La classe comme constructeur d'objets Pourquoi est-il important de définir les constructeurs d’objets? Une classe sans constructeurs a plusieurs inconvénients: dans la déclaration de la classe, on ne voit pas bien quelle structure d'objets (ou on pourrait dire quel schéma de la classe) va être donnée pour ses objets, en apparence en tous cas, rien n'empêche qu'un objet d'une classe possède (ou pas) n'importe quel attribut, si nous voulons écrire un algorithme ou une fonction s'appliquant à une collection d'objets de la même classe, on aimerait bien savoir sur quels attributs on peut compter de façon certaine pour tous les objets ⇒ On va se donner un moyen d'uniformiser les objets d'une classe en les construisant. 17 Constructeur d’objets On va ajouter une fonction spéciale à la définition de la classe (on verra plus loin qu'on appelle une telle fonction une méthode). Le rôle de cette méthode __init__() est de fixer au moment de la création de tout objet de cette classe, la liste et la valeur des attributs initiaux. Une fois l'objet créé, la valeur de ces attributs peut encore changer. La méthode __init__(self, param1, param2, param3,....) s’appelle le constructeur de la classe. Exemple: class Personne: "Une personne a un nom et d’autres attributs" def __init__(self, n, p, s): self.nom = n self.prenom = p self.sport = s 18 Constructeur d’objets class Personne: "Une personne a un nom et d’autres attributs" def __init__(self, n, p, s): self.nom = n self.prenom = p self.sport = s p1 = Personne(n='Enfayitte', p='Mélusine', s='natation') p2 = Personne(n='Tarénaze', p='Maguy', s='curling') p3 = Personne('Apajivay', 'Steve', 'ski') # Ceci fonctionne aussi Le paramètre self représente l’objet qu’on est en train de fabriquer. link on pythontutor 19 Constructeur d’objets - autre exemple class Rectangle: "a rectangle is defined by two dimensions: height, and width." def __init__(self, h, w): self.height = h self.width = w r1 = Rectangle(150, 300) r2 = Rectangle(200, 200) 20 Calculer l'aire totale d'une collection de rectangles from random import randint #1: creation de la collection maCollection = [] for i in range(100): newRectangle = Rectangle(h=randint(30, 300), # un nb aléatoire entre 30 et 300 w=randint(50, 500)) # un nb aléatoire entre 50 et 500 maCollection.append(newRectangle) #2: calcul de la surface totale total = 0 for r in maCollection: total = total + (r.height * r.width) print('Ma collection couvre une surface totale de', total, 'm2.') 21 Modification des objets Nous pouvons changer les propriétés d’un objet en assignant de nouvelles valeurs à ses attributs. Par exemple, nous pouvons modifier la taille d’un rectangle (sans modifier sa position), en réassignant ses attributs hauteur et largeur : boite = Rectangle(150, 300) boite.height = boite.height + 20 boite.width = boite.width – 5 22 Similitude et égalité La similitude entre deux (ou plus) objets signifie que ces deux objets contiennent les mêmes données (leurs attributs). p1 = Point(3, 4) p2 = Point(3, 4) print(p1 == p2) False L'égalité signifie que deux (ou plus) print(p1.x == p2.x) True variables référencent le même objet (ils sont des alias l’une de l’autre) 23 Double soulignement avant et après un nom Ce sont des noms de méthodes spéciaux utilisés par Python. Il ne s’agit que d’une convention, d’une manière pour le système Python d’utiliser des noms qui ne seront pas en conflit avec les noms définis par l’utilisateur. Vous substituez ensuite généralement ces méthodes et définissez (ou redéfinissez) le comportement souhaité pour cette classe d'objets lorsque Python les appelle. Par exemple, on (re-)définit la méthode __init__() lors de l'écriture d'une classe, pour donner la méthode de construction des objets. 24 Namespace: le rôle des noms de variables Pour le dire simplement, un espace de noms est la collection des noms de variables et de fonctions qu'une ligne de code Python peut manipuler, utiliser. Selon où se trouve cette ligne de code, l'espace des noms disponibles change: en considérant l'imbrication des déclarations, c'est l'espace le plus proche de la ligne. Si Python doit évaluer une variable a dans une fonction, il va chercher d'abord au plus près dans la fonction, puis s'il ne trouve pas, il cherche une variable a dans le module, puis s'il ne trouve toujours pas, il cherche un a dans l'espace général des variables (Buit-in). Voyons un exemple: (slide suivant) 25 plus Namespace : exemple 0.20 0.05 A la ligne 4 de la fonction, la valeur de la variable factor est prise dans la fonction : 0.20 x = 100, factor = 0.20, résultat = 120. 26 plus Namespace : autre exemple avec un objet ligne 5 et 6, a désigne la variable connue dans l'espace de la cellule (= 'boo') ligne 3 et 8, a désigne l'attribut a de l'objet t (= 20) 27 plus Préparez et posez vos questions! 28 15m C06.3 - Les méthodes : des fonctions propres aux objets 29 Les méthodes : des fonctions propres aux objets d'une classe On a vu comment définir des attributs propres aux objets d'une classe. La classe peut définir des propriétés plus dynamiques de ses objets: en donnant des fonctions attachées à la définition de la classe, qu'on appelle des méthodes: class Personne: "Une personne a un nom, un prenom, et..." def __init__(self, n, p, a, s): def titreComplet(self): self.nom = n "calcule la chaine du titre complet" self.prenom = p if self.sexe == 'M': self.anneeNaiss = a return 'Monsieur ' + self.prenom self.sexe = s + ' ' + self.nom else: def age(self): return 'Madame ' + self.prenom "calcule l'age en année de la personne" + ' ' + self.nom today = date.today() birth = date(self.anneeNaiss, 1, 1) Note : pour utiliser les fonctions de date, il faut les return (today - birth).days // 365 importer une fois au début de votre code avec from datetime import date 30 Autre exemple: Des rectangles avec deux méthodes: une pour donner l'aire du rectangle, une autre pour donner son périmètre: class Rectangle: "a rectangle has a width and an height" def __init__(self, h, w): r1 = Rectangle(20, 30) self.height = h r2 = Rectangle(20, 50) self.width = w if r1.area() > 1000: print('r1 est un grand rectangle !') def area(self): return self.height * self.width r1.perimeter() < r2.perimeter() def perimeter(self): True return 2 * (self.height + self.width) 31 Une erreur courante r1 = Rectangle(20, 30) r2 = Rectangle(20, 50) print(Rectangle.area()) # erreur On ne sait pas de quel triangle on parle dans area() On doit utiliser p.ex. pour le rectangle 1 ! print(r1.area()) 32 A quel moment sont calculées les méthodes ? Il faut comprendre que les méthodes ne sont calculées qu'au moment où on les appelle, et non pas au moment où on définit la classe. Pour les rectangles, la valeur de l'aire ou du périmètre ne sont pas calculées à l'avance, mais au moment où on invoque r.area(). ⇒ si la largeur du rectangle r.width augmente un peu au cours du programme, alors l'appel des méthodes r.area() et r.perimeter() donnera à tout moment la bonne valeur, c'est-à-dire celle qui est en vigueur au moment de l'appel. Les méthodes r.area() et r.perimeter() fournissent des propriétés dynamiques des objets Rectangle. p4.sexe = 'F' p4.titreComplet() → 'Madame Alonzo Bistro' 33 Modifiers (modificateurs) Il est parfois utile qu'une méthode modifie un class MyTime: objet en utilisant les valeurs qu'elle obtient en def __init__(self, hrs=0, mins=0, secs=0): paramètres. "Create a MyTime object" self.hours = hrs self.minutes = mins Les méthodes comme increment qui self.seconds = secs fonctionnent de cette façon sont appelées modificateurs. def increment(self, secs): "add some seconds to this time" self.seconds += secs while self.seconds >= 60: self.seconds = self.seconds - 60 self.minutes = self.minutes + 1 while self.minutes >= 60: self.minutes = self.minutes - 60 self.hours = self.hours + 1 return self 34 Redéfinition des opérateurs (surcharge) Certains langages, notamment Python, permettent d’avoir différentes significations pour le même opérateur lorsqu’ils sont appliqués à différents types. Par exemple, + en Python signifie des choses très différentes pour les entiers et pour les chaînes. Cette fonctionnalité s'appelle la surcharge de l'opérateur. Exemple: 35 Préparez et posez vos questions! 36 15m C06.4 - Classes d’objets Python : schémas de classes UML 37 Classes d’objets: schémas de classes UML On a vu (cours Modèles Informatiques) comment donner un modèle conceptuel d'une base de données à l'aide de schémas de classes avec la notation UML. On va illustrer ici comment utiliser UML pour donner un modèle conceptuel de toutes les classes impliquées dans un petit exemple: Nom de la classe Attributs de la classe Méthodes de la classe 38 Notre exemple en python (voir le notebook C06 Teacher) class Department: "a deparment, with employees" Nom de la classe def __init__(self, n): self.name = n Attribut self.staff = [] # initially, no employees, we will hire them. def hire(self, emp): Méthode "hire employee e in department" self.staff.append(emp) return self class Employee: "an employee" def __init__(self, f, l, y): self.first_name = f self.last_name = l self.hiring_year = y def nb_years_in_company(self): "returns the nb of years employee worked since hiring." this_year = date.today().year return this_year - self.hiring_year 39 Notre exemple en python (voir le notebook C06 Teacher) class Project: "a project is for a department and has employees from the department working for it" def __init__(self, n, d): self.name = n self.for_department = d self.project_team = [] # initially the project team is empty def assign(self, emp): "assign an employee to a project" if emp in self.for_department.staff: self.project_team.append(emp) else: print("Error: employee:", emp.last_name, " cannot board project:", self.name) return self 40 des objets dans ces trois classes: sales = Department('Sales') account = Department('Accounting') tony = Employee('Antonio', 'Smith', 2011) mary = Employee('Mary', 'Brown', 2009) superProj1 = Project('m-Sales for All', sales) superProj2 = Project('Rocket Account', account) sales.hire(tony) account.hire(mary) Il semble qu’on ne puisse pas superProj1.assign(tony) superProj1.assign(mary) ajouter mary à ce super projet. Retrouvez pourquoi en → Error: employee: Brown cannot board project: m-Sales for All consultant le code de la méthode.assign(emp) 41 réponse: la réponse est simple à obtenir en python: 42 Préparez et posez vos questions! 43 Références et matériel de soutien Chapter 11, 12 of course book [url] “How to think like a computer scientist” [url], chapter 15, 16 and 21 Python Documentation: Classes [url] 44

Use Quizgecko on...
Browser
Browser