Python - Classe Singleton
Bonjour à tous, émerveillés programmeurs ! Aujourd'hui, nous allons entamer un voyage passionnant dans le monde de la programmation Python. Vers où ? Vers la terre mystique des Classes Singleton ! Ne vous inquiétez pas si cela vous paraît un peu intimidant – je promets que à la fin de ce tutoriel, vous serez un maître des Singletons. Alors, plongeons-y !
Qu'est-ce qu'une Classe Singleton ?
Avant de commencer à coder, comprenons ce qu'est une classe Singleton. Imaginez que vous jouez à un jeu vidéo et qu'il n'y a qu'un seul personnage que vous contrôlez tout au long du jeu. Peu importe combien de fois vous sauvegardez et rechargez le jeu, vous contrôlez toujours le même personnage. C'est essentiellement ce qu'une classe Singleton fait en programmation – elle garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à cette instance.
Création de Classes Singleton en Python
En Python, il y a plusieurs moyens de créer une classe Singleton. Nous allons explorer deux méthodes principales : l'utilisation de __init__
et l'utilisation de __new__
. Mais d'abord, voyons pourquoi nous pourrions avoir besoin d'une classe Singleton.
Pourquoi Utiliser un Singleton ?
Les Singletons sont utiles lorsque vous voulez vous assurer qu'il n'existe qu'une seule instance d'une classe tout au long de votre programme. Cela peut être utile pour :
- Gérer l'état global
- Coordonner des actions à travers un système
- Gérer une ressource partagée, comme une connexion de base de données
Maintenant, mettons-nous au travail !
Utilisation de init
Notre première méthode implique l'utilisation de la méthode __init__
, qui est appelée lors de la création d'un objet. Voici comment nous pouvons créer un Singleton en utilisant __init__
:
class Singleton:
_instance = None
def __init__(self):
if Singleton._instance is None:
Singleton._instance = self
else:
raise Exception("Cette classe est un singleton !")
@staticmethod
def get_instance():
if Singleton._instance is None:
Singleton()
return Singleton._instance
# Utilisation
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2) # Sortie : True
# Cela lèvera une exception
# s3 = Singleton()
Voici ce que cela signifie :
- Nous définissons une variable de classe
_instance
pour contenir notre seule instance. - Dans la méthode
__init__
, nous vérifions si une instance existe déjà. Si non, nous en créons une. Si oui, nous levons une exception. - Nous fournissons une méthode
get_instance()
pour accéder à notre Singleton. Cette méthode crée une instance si elle n'en existe pas, ou retourne l'instance existante.
Lorsque nous exécutons ce code, s1
et s2
seront la même instance. Essayer de créer une nouvelle instance directement (comme s3 = Singleton()
) lèvera une exception.
Utilisation de new
Maintenant, examinons une autre méthode utilisant __new__
. Cette méthode est appelée avant __init__
lors de la création d'une nouvelle instance.
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# Utilisation
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # Sortie : True
Voici ce qui se passe :
- Nous redéfinissons la méthode
__new__
, qui est responsable de la création et du retour d'une nouvelle instance. - Si
_instance
est None, nous créons une nouvelle instance en utilisantsuper().__new__(cls)
. - Nous retournons toujours
_instance
, qu'il soit nouvellement créé ou déjà existant.
Cette méthode est un peu plus concise et n'a pas besoin d'une méthode get_instance()
séparée.
Comparaison des Deux Méthodes
Comparons ces méthodes dans un tableau pratique :
Méthode | Pros | Cons |
---|---|---|
__init__ |
- Contrôle plus explicite - Peut empêcher l'instanciation directe |
- Nécessite une méthode get_instance() séparée- Un peu plus complexe |
__new__ |
- Plus concise - Fonctionne avec l'instanciation directe |
- Moins de contrôle explicite - Peut être moins intuitif pour les débutants |
Les deux méthodes atteignent le même objectif, donc le choix se fait souvent en fonction des préférences personnelles ou des exigences spécifiques de votre projet.
Un Exemple du Monde Réel
Pour finir, examinons un exemple du monde réel. Imaginez que nous créons un jeu et que nous voulons nous assurer qu'il n'y a qu'un seul personnage joueur :
class PlayerCharacter:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.name = "Héro"
cls._instance.health = 100
cls._instance.level = 1
return cls._instance
def level_up(self):
self.level += 1
print(f"{self.name} a atteint le niveau {self.level} !")
# Utilisation
player1 = PlayerCharacter()
player2 = PlayerCharacter()
print(player1.name) # Sortie : Héro
print(player2.name) # Sortie : Héro
player1.level_up() # Sortie : Héro a atteint le niveau 2 !
print(player2.level) # Sortie : 2
Dans cet exemple, peu importe combien de fois nous créons un PlayerCharacter
, nous obtenons toujours la même instance. Cela garantit que notre jeu n'a qu'un seul personnage joueur, en maintenant un état cohérent tout au long du jeu.
Et voilà ! Vous avez juste maîtrisé l'art de créer des classes Singleton en Python. Rappelez-vous, comme tout outil puissant, utilisez les Singletons avec sagesse. Ils sont excellents pour gérer l'état global ou les ressources partagées, mais une utilisation excessive peut rendre votre code plus difficile à tester et à maintenir.
Continuez à pratiquer, à coder, et surtout, à vous amuser ! À la prochaine fois, heureux programmation !
Credits: Image by storyset