Aller au contenu
> 💻 🧠 Code 1001 > 📚 Supports d'Apprentissage > 🐍 Python > Classes en Python, POO et Gestionnaires de Contexte : Guide Complet

Classes en Python, POO et Gestionnaires de Contexte : Guide Complet

  • par

1. Classes en Python

Les classes sont un mécanisme clé de la POO. Une classe est un modèle pour créer des objets avec des attributs (données) et des méthodes (fonctions). Les objets créés à partir d’une classe sont appelés instances. Les classes permettent de structurer le code, améliorer sa réutilisation et faciliter la maintenance.

Structure d’une classe

class ClassName:
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2

    def method(self):
        return f'{self.param1} et {self.param2}'

Points clés :

  • __init__ : constructeur pour initialiser les attributs de l’objet.
  • self : référence à l’instance courante.
  • Attributs : définis via self, accessibles dans toutes les méthodes.
  • Méthodes : manipulent les données de l’objet.

Création d’objets

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def description(self):
        return f'{self.year} {self.make} {self.model}'

my_car = Car('Toyota', 'Corolla', 2020)
print(my_car.description())  # Sortie: 2020 Toyota Corolla

Types de méthodes

  1. Méthodes d’instance — fonctionnent sur les objets (self).
  2. Méthodes de classe — fonctionnent sur la classe (cls) via @classmethod.
  3. Méthodes statiques — indépendantes de l’instance et de la classe (@staticmethod).

Héritage

class Animal:
    def speak(self):
        return 'Son animal'

class Dog(Animal):
    def speak(self):
        return 'Ouaf'

Polymorphisme

class Cat(Animal):
    def speak(self):
        return 'Miaou'

cat = Cat()
print(cat.speak())  # Sortie: Miaou
  • La même méthode fonctionne différemment selon le type d’objet.

Encapsulation

class Car:
    def __init__(self, make, model):
        self._make = make  # Attribut protégé
        self._model = model

    def get_make(self):
        return self._make

    def set_make(self, make):
        self._make = make

Méthodes magiques et destructeur

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Point({self.x}, {self.y})'

p = Point(3, 4)
print(p)  # Sortie: Point(3, 4)

Diagramme ASCII : Héritage et Polymorphisme

       ┌─────────┐
       │ Animal  │
       └─────────┘
       │ speak() │
       └─────────┘
            ▲
    ┌───────┴────────┐
    │                │
┌─────────┐      ┌─────────┐
│  Dog    │      │  Cat    │
└─────────┘      └─────────┘
│ speak() │      │ speak() │
└─────────┘      └─────────┘

2. Gestionnaires de Contexte en Python

Les gestionnaires de contexte permettent d’allouer et de libérer automatiquement des ressources, garantissant un nettoyage correct même en cas d’erreurs.

Utilisation de @contextmanager

from contextlib import contextmanager

@contextmanager
def my_context():
    print("Entrée dans le contexte")
    try:
        yield "Ressource"
    finally:
        print("Sortie du contexte")

Usage :

with my_context() as res:
    print("Dans le contexte :", res)

Capture de stdout/stderr et Tee

Python permet de capturer stdout, stderr ou les deux, et de montrer et capturer simultanément avec le patron Tee.


3. Exemple complet : oop_and_context.py

"""
oop_and_context.py

Exemples de classes, principes POO et gestionnaires de contexte en Python.
Inclut :
- Définition de classes, héritage, polymorphisme, encapsulation
- Méthodes d’instance, de classe et statiques
- Méthodes magiques et destructeur
- Gestionnaires de contexte avec @contextmanager
- Capture de stdout, stderr et capture combinée
- Patron Tee : sortie visible et capture simultanée
- Gestionnaire de contexte basé sur une classe
"""

import sys
import io
from contextlib import contextmanager

# ==========================
# Partie 1 : Classes et POO
# ==========================

class Animal:
    """Classe de base pour les animaux."""
    def speak(self):
        return 'Son animal'

class Dog(Animal):
    def speak(self):
        return 'Ouaf'

class Cat(Animal):
    def speak(self):
        return 'Miaou'

class Car:
    """Exemple de classe avec encapsulation."""
    def __init__(self, make, model, year=None):
        self._make = make
        self._model = model
        self.year = year

    def get_make(self):
        return self._make

    def set_make(self, make):
        self._make = make

    def description(self):
        if self.year:
            return f'{self.year} {self._make} {self._model}'
        return f'{self._make} {self._model}'

class Point:
    """Classe avec méthodes magiques."""
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Point({self.x}, {self.y})'

# ==========================
# Partie 2 : Gestionnaires de contexte
# ==========================

@contextmanager
def my_context():
    print("Entrée dans le contexte")
    try:
        yield "Ressource"
    finally:
        print("Sortie du contexte")

@contextmanager
def capture_stdout():
    old_stdout = sys.stdout
    sys.stdout = buffer = io.StringIO()
    try:
        yield buffer
    finally:
        sys.stdout = old_stdout

@contextmanager
def capture_stderr():
    old_stderr = sys.stderr
    sys.stderr = buffer = io.StringIO()
    try:
        yield buffer
    finally:
        sys.stderr = old_stderr

@contextmanager
def capture_output():
    old_stdout = sys.stdout
    old_stderr = sys.stderr
    sys.stdout = sys.stderr = buffer = io.StringIO()
    try:
        yield buffer
    finally:
        sys.stdout = old_stdout
        sys.stderr = old_stderr

class Tee(io.StringIO):
    """Sortie visible et capture simultanée."""
    def __init__(self, original):
        super().__init__()
        self.original = original

    def write(self, text):
        self.original.write(text)
        super().write(text)

    def flush(self):
        self.original.flush()

@contextmanager
def capture_stdout_tee():
    old_stdout = sys.stdout
    sys.stdout = tee = Tee(old_stdout)
    try:
        yield tee
    finally:
        sys.stdout = old_stdout

# ==========================
# Partie 3 : Gestionnaire de contexte basé sur classe
# ==========================

class OutputCapture:
    """Gestionnaire de contexte basé sur classe pour capturer stdout."""
    def __init__(self):
        self._buffer = io.StringIO()
        self._old_stdout = None

    def __enter__(self):
        self._old_stdout = sys.stdout
        sys.stdout = self._buffer
        return self._buffer

    def __exit__(self, exc_type, exc_val, exc_tb):
        sys.stdout = self._old_stdout
        return False  # propager les exceptions

# ==========================
# Partie 4 : Démonstrations
# ==========================

def demo_classes():
    print("\n--- Démonstration des Classes ---")
    dog = Dog()
    cat = Cat()
    print("Chien dit :", dog.speak())
    print("Chat dit :", cat.speak())

    my_car = Car('Toyota', 'Corolla', 2020)
    print("Description de la voiture :", my_car.description())
    my_car.set_make('Honda')
    print("Marque mise à jour :", my_car.get_make())

    point = Point(3, 4)
    print("Point :", point)

def demo_context_managers():
    print("\n--- Démonstration des Gestionnaires de Contexte ---")
    with my_context() as res:
        print

(« Dans le contexte : », res)

with capture_stdout() as out:
    print("stdout capturé")
print("Contenu :", out.getvalue().strip())

with capture_stderr() as err:
    print("Cela va vers stdout")
    sys.stderr.write("Message d'erreur\n")
print("Erreurs :", err.getvalue().strip())

with capture_output() as out_all:
    print("Stdout dans capture combinée")
    sys.stderr.write("Stderr dans capture combinée\n")
print("Sortie combinée :", out_all.getvalue().strip())

with capture_stdout_tee() as tee_out:
    print("Sortie visible ET capturée avec Tee")
print("Buffer Tee :", tee_out.getvalue().strip())

with OutputCapture() as class_capture:
    print("Capture utilisant le gestionnaire basé sur classe")
print("Buffer du gestionnaire de classe :", class_capture.getvalue().strip())

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *