La méthode __init__ est une fonction (plus exactement une méthode, mais nous avons vu que c'était la même chose), comme toutes fonctions on peut lui passer des paramètres sous forme de variable (comme déjà vu précédemment avec les fonctions).

Le passage de paramètres se fait au moment de la création de l'instance :

À faire vous même 4.1

Saisissez, analysez et testez ce code


#!/usr/bin/env python
# -*- coding: utf-8 -*-
class personnage(object):
    #on définit la méthode qui va initialiser les attributs, elle possède maintenant un paramètre supplémentaire.
    def __init__(self,nbreDeVie):
        #l'attribut self.vie est initialisé avec la valeur de nbreDeVie
        self.vie=nbreDeVie
# on crée une instance de la classe personnage nommée Gollum et on initialise la variable nbreDeVie avec la valeur 20
gollum=personnage(20)
# on crée une autre instance de la classe personnage nommée Bilbo et on initialise la variable nbreDeVie avec la valeur 20
bilbo=personnage(20)
#le reste du code reste identique
print ('Bilbo a '+str(bilbo.vie)+' points de vie')
print ('Gollum a '+str(gollum.vie)+' points de vie')
print ('Bilbo est blessé par Gollum')
bilbo.vie=bilbo.vie-1
print ('Bilbo a '+str(bilbo.vie)+' points de vie')
print ('Gollum a '+str(gollum.vie)+' points de vie')
			

Quelques explications sur l'exemple 4.1 :

Au moment de la création de l'instance gollum, on passe comme argument le nombre de vies (gollum=personnage (20)). Ce nombre de vies est attribué au premier argument de la méthode __init__ , la variable nbreDeVie (nbreDeVie n'est pas tout à fait le premier argument de la méthode __init__ puisque devant il y a self, mais bon, self étant obligatoire, nous pouvons dire que nbreDeVie est le premier argument non obligatoire).

Ensuite, on attribue la valeur contenue dans la variable nbreDeVie à l'attribut self.vie (ligne self.vie=nbreDeVie)

N.B. Je parle bien de variable pour nbreDeVie (car ce n'est pas un attribut de la classe personnage puisqu'elle ne commence pas par self).

Bien évidemment, nous pouvons passer plusieurs arguments à la méthode __init__ (comme pour n'importe quelle fonction), nous verrons des exemples dans un instant.

Cela va déjà mieux, mais tout n'est pas encore parfait. En effet, nous voyons encore se « balader » des « gollum.vie » en dehors de la classe (notamment dans gollum.vie= gollum.vie-1 ou encore dans les lignes qui permettent d'afficher le nombre de vies restantes), ce qui pose encore un problème au niveau de l'encapsulation.

Pour résoudre ce problème, nous allons créer 2 nouvelles méthodes :

À faire vous même 4.2

Saisissez, analysez et testez ce code


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Définit une classe
class personnage(object):
    #méthode __init__ avec 2 arguments (sans compter self !) le nombre de vies et le nom du personnage
    def __init__(self, nbreDeVie, nomDuPerso):
        self.vie=nbreDeVie
        self.nom=nomDuPerso
    #voici la méthode qui affiche l'état du personnage (attention de bien mettre l'argument self, il est obligatoire.
    def afficheEtat (self):
        print ('Il reste '+str(self.vie)+' points de vie à '+self.nom)
    #voici la méthode qui fait perdre 1 point de vie au personnage qui a subit une attaque
    def perdVie (self):
        print (self.nom+' subit une attaque, il perd une vie')
        self.vie=self.vie-1
#la "fabrication" de la classe est terminée,
#la suite du programme est uniquement composée de création d'instances et d'appel de méthodes
#on crée l'instance gollum sans oublier de passer le nombre de points de vie et le nom du personnage
gollum=personnage(20,'Gollum')
#on appelle la méthode afficheEtat pour l'instance gollum
gollum.afficheEtat()
bilbo=personnage(20,'Bilbo')
#on appelle la méthode afficheEtat pour l'instance bilbo
bilbo.afficheEtat()
#on appelle la méthode perdVie pour l'instance bilbo
bilbo.perdVie()
#on appelle de nouveau la méthode afficheEtat pour l'instance gollum
gollum.afficheEtat()
#et pour l'instance bilbo
bilbo.afficheEtat()
			

Voilà, nous arrivons enfin, dans l'exemple 4.2, à un programme qui respecte l'encapsulation. En dehors de la création des classes, un bon programme orienté objet, ne sera qu'une suite de création d'instances et d'appel de méthode pour ces instances (bien évidemment l'appel de telle ou telle méthode pourra se faire en fonction de certaines conditions, nous verrons cet aspect des choses un peu plus loin).

NB: Dans l'exemple 4.2 lors de la création de Bilbo et Gollum, on passe 20 comme argument nbreDeVie, bien évidemment, vous pouvez choisir n'importe quelle valeur (si par exemple au départ vous décidez que Gollum est en moins bon état que Bilbo, vous pouvez lui donner seulement 15 points de vie :


gollum=personnage(15,'Gollum')
			

Mais que se passe-t-il si on oublie de passer des arguments au moment de la création d'une instance ?(ex: Gandalf=personnage()). Vous aurez le droit à une erreur du style :  "lors de la création d'une instance de personnage, j'attends des arguments, or, ici il n'y en a pas !"

Nous pouvons très facilement résoudre le problème en donnant des valeurs par défaut (si j'oublie les arguments se sont les valeurs données par défaut qui seront données aux attributs). Les valeurs par défaut sont données au moment de la création de la méthode __init__

À faire vous même 4.3

Saisissez, analysez et testez ce code


#!/usr/bin/env python
# -*- coding: utf-8 -*-
class personnage(object):
    #méthode __init__ avec les 2 arguments et des valeurs données par défaut
    #si vous oubliez les arguments votre instance aura pour nom Sans Nom et 20 points de vie
    def __init__(self, nbreDeVie=20, nomDuPerso='Sans Nom'):
        self.vie=nbreDeVie
        self.nom=nomDuPerso
    def afficheEtat (self):
        print ('Il reste '+str(self.vie)+' point de vie à '+self.nom)
    def perdVie (self):
        print (self.nom+' subit une attaque, il perd une vie')
        self.vie=self.vie-1
#on crée une nouvelle instance en "oubliant" les arguments.
gandalf=personnage()
#Et pourtant.......tout fonctionne avec les valeurs par défaut
gandalf.afficheEtat()