jusqu’ici on a vu le modèle usuel, dans lequel
une instance possède des attributs de données
une classe possède des méthodes
une méthode prend un objet comme premier paramètre
dans ce notebook on va voir que ce modèle peut être un peu courbé, c’est-à-dire que:
une classe peut aussi avoir des attributs de données
une méthode peut ne pas prendre un objet en paramètre
une méthode peut même prendre plutôt .. une classe en paramètre (un peu plus avancé)
attributs de classe¶
dans (l’espace de nom d’)une classe, on peut mettre
des méthodes (on le savait)
et aussi attributs normaux - qui référencent des données
rien de nouveau point de vue syntaxe :
on écrit juste la déclaration dans la classe,
au même niveau d’imbrication que les méthodes
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)1s2 = Student('jean')
len(s1.all_instances), len(Student.all_instances)(2, 2)