Menu
Coddy logo textTech

Méthodes statiques et de classe

Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 39 sur 64.

Outre les méthodes d'instance régulières, les classes peuvent avoir des méthodes statiques et des méthodes de classe qui servent des objectifs différents.

Voici un exemple de méthode statique :

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def is_even(number):
        return number % 2 == 0

Les méthodes statiques n'ont pas besoin de self et fonctionnent comme des fonctions régulières. Appelez-les directement depuis la classe :

result = MathHelper.add(5, 3)
print(result)

check = MathHelper.is_even(10)
print(check)

Voici un exemple de méthode de classe :

class Person:
    count = 0  # Variable de classe
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

Les méthodes de classe reçoivent la classe elle-même (cls) comme premier paramètre :

person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_count())  # 2

Utilisez les méthodes de classe comme constructeurs alternatifs :

anonymous = Person.create_anonymous()
print(anonymous.name)      # Anonyme
print(Person.get_count())  # 3

Comparez les trois types de méthodes dans une seule classe :

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # Méthode d'instance - nécessite self, accède aux données de l'instance
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # Méthode de classe - nécessite cls, accède aux données de la classe
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # Méthode statique - ne nécessite ni l'un ni l'autre, juste une fonction utilitaire
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Appartient à Alice
print(Calculator.get_brand())   # Python Calc
print(Calculator.multiply(4, 5)) # 20

Sortie :

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

Vous pouvez également appeler des méthodes de classe et statiques à partir d'instances :

calc = Calculator("Bob")
print(calc.get_brand())      # Python Calc
print(calc.multiply(2, 3))   # 6

Différences clés :

  • Méthodes d'instance : Nécessitent self, accèdent aux données de l'instance
  • Méthodes de classe : Nécessitent cls, accèdent aux données de la classe, utiles pour les constructeurs alternatifs
  • Méthodes statiques : N'ont besoin d'aucun des deux, simples fonctions utilitaires liées à la classe

Point clé : Utilisez @staticmethod pour les fonctions utilitaires qui appartiennent logiquement à la classe mais n'ont pas besoin de données de classe ou d'instance. Utilisez @classmethod lorsque vous avez besoin d'accéder à la classe elle-même, comme pour des constructeurs alternatifs ou pour accéder à des variables de classe.

challenge icon

Défi

Facile

Dans ce défi, vous allez implémenter une classe Temperature avec des fonctionnalités spécifiques tout en exploitant un framework de test complet.

Vous devez modifier uniquement le fichier temperature.py, en suivant les commentaires TODO qui guident votre implémentation. La classe doit inclure :

  • Une variable de classe pour suivre les relevés de température
  • Une méthode statique pour la conversion de température
  • Des méthodes de classe pour ajouter des relevés et calculer les moyennes

Aide-mémoire

Les classes peuvent avoir trois types de méthodes : les méthodes d'instance, les méthodes statiques et les méthodes de classe.

Les méthodes statiques utilisent le décorateur @staticmethod, n'ont pas besoin de self, et fonctionnent comme des fonctions régulières :

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b

# Appel direct depuis la classe
result = MathHelper.add(5, 3)

Les méthodes de classe utilisent le décorateur @classmethod et reçoivent la classe (cls) comme premier paramètre :

class Person:
    count = 0
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

# Utilisation
print(Person.get_count())
anonymous = Person.create_anonymous()

Différences clés :

  • Méthodes d'instance : Nécessitent self, accèdent aux données de l'instance
  • Méthodes de classe : Nécessitent cls, accèdent aux données de la classe, utiles pour les constructeurs alternatifs
  • Méthodes statiques : N'ont besoin ni de l'un ni de l'autre, ce sont juste des fonctions utilitaires liées à la classe

Les méthodes de classe et les méthodes statiques peuvent toutes deux être appelées depuis la classe ou depuis les instances :

Calculator.multiply(4, 5)  # Depuis la classe
calc.multiply(4, 5)        # Depuis l'instance

Essayez vous-même

from temperature import Temperature

# Gestionnaire de cas de test pour des tests complets
test_case = input()

if test_case == "default_test":
    # Tester la fonctionnalité de base
    Temperature.celsius_readings = []
    Temperature.add_reading(25)
    Temperature.add_reading(30)
    Temperature.add_reading(27)
    
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"22°C is {Temperature.celsius_to_fahrenheit(22)}°F")

elif test_case == "empty_readings":
    # Tester average_reading sans aucun relevé
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # Tester avec un seul relevé
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # Tester avec des valeurs de température négatives
    Temperature.celsius_readings = []
    Temperature.add_reading(-10)
    Temperature.add_reading(-20)
    Temperature.add_reading(-30)
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"-15°C is {Temperature.celsius_to_fahrenheit(-15)}°F")

elif test_case == "zero_value":
    # Tester avec un relevé de 0°C
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # Tester avec des valeurs de température extrêmes
    absolute_zero = -273.15  # zéro absolu en Celsius
    sun_surface = 5500  # température approximative de la surface du soleil en Celsius
    
    print(f"{absolute_zero}°C is {Temperature.celsius_to_fahrenheit(absolute_zero)}°F")
    print(f"{sun_surface}°C is {Temperature.celsius_to_fahrenheit(sun_surface)}°F")

elif test_case == "reset_readings":
    # Tester la réinitialisation des relevés
    Temperature.celsius_readings = []
    Temperature.add_reading(10)
    Temperature.add_reading(20)
    Temperature.add_reading(30)
    print(f"Average reading before reset: {Temperature.average_reading()}")
    
    Temperature.celsius_readings = []
    print(f"Average reading after reset: {Temperature.average_reading()}")

elif test_case == "decimal_values":
    # Tester avec des valeurs décimales
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # Température corporelle normale
    Temperature.add_reading(37.2)  # Légère fièvre
    Temperature.add_reading(36.9)  # Variation normale
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # Tester avec de nombreux relevés
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming