Skip to article frontmatterSkip to article content

jusqu’ici on a vu le modèle usuel, dans lequel

dans ce notebook on va voir que ce modèle peut être un peu courbé, c’est-à-dire que:

attributs de classe

dans (l’espace de nom d’)une classe, on peut mettre

rien de nouveau point de vue syntaxe :

voyons cela sur un exemple

class Student:

    all_students = []   # ici all_students est un attribut
                        # de la classe, et pas des instances

    def __init__(self, name):
        self.name = name
        
        # on peut y faire référence
        # en partant de la classe
        
        Student.all_students.append(self)
s = Student('jean')

# on peut faire référence à cet attribut comme ceci
#                                 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 
print(f"after step 1 we have {len(Student.all_students)} students")
after step 1 we have 1 students
# est-ce que ceci va fonctionner aussi ?

print(f"after step 1 we have {len(s.all_students)} students")
after step 1 we have 1 students
# du coup on peut comme cela agréger des choses relatives
# à tous les objets de la classe

s = Student('pierre')
print(f"after step 2 we have {len(Student.all_students)} students")
after step 2 we have 2 students

méthodes statiques

une technique utile pour exposer des pseudo-constructeurs

class Student:

    def __init__(self, name):
        self.name = name

    # on ne peut pas appeler cette méthode
    # avec un objet de type Student,
    # puisque précisément, c'est son propos
    # de construire un objet

    @staticmethod
    def load_from_file(filename):
        with open(filename) as f:
            return Student(f.readline().strip())
# et on l'appelle comme ceci

s1 = Student.load_from_file('student1.txt')
s2 = Student.load_from_file('student2.txt')

# et si on inspecte leur contenus
s1.name, s2.name
('jean', 'pierre')

méthodes de classe

sujet avancé, lié au précédent, mais d’utilisation plus rare:

class Student:

    all_instances = []

    # avec cette déclaration, ce n'est pas 
    # l'objet qui est passé en paramètre à 
    # la méthode, mais sa classe !
    
    @classmethod
    def record_instance(cls, instance):
        cls.all_instances.append(instance)
        
    def __init__(self, name):
        self.name = name
        self.record_instance(self)
s1 = Student('jean')

len(s1.all_instances)
1
s2 = Student('jean')

len(s1.all_instances), len(Student.all_instances)
(2, 2)