Date de première publication : 2022/09/28
1. Gérer une classe simple
L'idée est de savoir créer une classe simple avec des attributs et des méthodes, l'instancier et la faire vivre.
1.1. Une classe vide
1.2. Une classe simple
Voici une déclaration "classique" d'une classe avec un attribut et une méthode pour accéder à cet attribut
Pour instancier la classe et manipuler l'attribut, directement ou par la méthode, cela donne le code suivant :
Que se passe-t-il si on change de "type" pour l'attribut ?
Cela ne pose pas de problème
On peut vérifier que le mot self
(qui n'est pas un mot-clé du langage) n'est qu'une convention :
On va vérifier maintenant ce qui se passe si un attribut est utilisé sans être défini :
On obtient alors le message suivant :
On peut alors - mais est-ce une bonne idée - le définir en dehors de __init__()
et cela va marcher !
Comme quoi, on peut faire n'importe quoi !!!
2. Variations sur le constructeur
2.1. Plusieurs constructeurs ?
Que se passe-t-il si on déclare plusieurs constructeurs pour une classe ?
Il n'y a pas de message d'erreur à la lecture du script mais seul le dernier constructeur est pris en compte, donc et1 est instancié mais pas et2.
2.2. Comment avoir "plusieurs" constructeurs ?
Il faut utiliser le système de valeur par défaut pour les paramètres...
Si l'on teste le code ci-dessous :
on obtient naturellement le message suivant :
On peut alors donner une valeur par défaut au paramètre name
, par exemple :
Que se passe-t'il si un argument avec une valeur par défaut est placé avant un autre argument ?
On pourra également avoir des méthodes de classes.
3. Encapsulation
3.1. Visibilité et limites
La visibilité en Python est une des plus grosses blagues qui soit ! Y en a pas !! On va tout de même tester les recommandations du PEP8 avec dans l'ordre
- Précéder le nom de l'attribut par un underscore pour donner
_name
ou_methode()
- Précéder le nom de l'attribut par un double underscore pour donner
__name
ou__methode()
Pour chacune des variantes, on peut tester, qu'en fait, ce n'est qu'une CONVENTION !
On peut voir que __name
a été renommé et que ce nom est toujours accessible de l'extérieur
essayez ensuite :
L'ajout d'attribut dynamique fait que l'on a créé un nouvel attribut __name
et donc après, il est accessible et est différent de l'attribut défini par le constructeur.
3.2. Intérêt de l'encapsulation
Coder la petite histoire du point et de ses coordonnées ...
4. Attributs et méthodes de classe
5. Syntaxe
Pour définir un attribut de classe, il suffit de l'initialiser dans la classe :
La question se pose de comment le manipuler dans une méthode telle que le constructeur (par exemple, incrémenter et afficher la valeur)
5.1. Des constantes ?
Les constantes n'existent pas en python. Le guide de style permet de les répérer en les écrivant en majuscules.
On peut utiliser des outils tels mypy pour spécifier les constantes et faire de la vérification AVANT l'exécution du code
mypy est utilisable pour faire de la vérification de "type" sur nos codes :
class Student: counter : int = 0 def __init(self, name : str) -> None : self.name = name Student.counter +=1 print(Student.counter) @classmethod def get_counter(cls) -> None: return cls.counterIl est légal de ne pas spécifier de type pour self
et cls
5.2. Créer des "constructeurs" multiples ?
Si vous reprenez l'exemple de la classe Point
développée pour l'encapsulation, on veut pouvoir créer des points de deux manières, soit en connaissant un couple (x, y), soit un couple (r,t). On a aucun moyen de faire cela en python mais pour être honnête, on ne pourrait pas le faire non plus avec un langage typé car les types sont les mêmes ...
6. Méthodes statiques
Après les méthodes d'instance, les méthodes classiques, il reste un dernier type de méthode à tester : les méthodes statiques. Elles n'ont besoin ni d'instance, ni de classe. On peut considérer que ce sont des fonctions rangées dans une classe (comme un espace de nommage)
L'usage du mot-clé static en python est différent des langages comme le C++ ou le Java.
J'ai déjà vu dans des codes une méthode statique manipuler un attribut de classe sous la forme Classe.attribut
mais je ne suis pas sur que ce soit une bonne pratique !