Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Ce cours existe en eBook.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !
Apprenez à programmer en Python

Apprenez à programmer en Python

Mis à jour le lundi 8 septembre 2014
  • 4 semaines
  • Facile

Les objets… vaste sujet ! Avant d'en créer, nous allons d'abord voir de quoi il s'agit. Nous allons commencer avec les chaînes de caractères, un type que vous pensez bien connaître.

Dans ce chapitre, vous allez découvrir petit à petit le mécanisme qui se cache derrière la notion d'objet. Ces derniers font partie des notions incontournables en Python, étant donné que tout ce que nous avons utilisé jusqu'ici… est un objet !

Vous avez dit objet ?

La première question qui risque de vous empêcher de dormir si je n'y réponds pas tout de suite, c'est :

Mais c'est quoi un objet ?

Eh bien, j'ai lu beaucoup de définitions très différentes et je n'ai pas trouvé de point commun à toutes ces définitions. Nous allons donc partir d'une définition incomplète mais qui suffira pour l'instant : un objet est une structure de données, comme les variables, qui peut contenir elle-même d'autres variables et fonctions. On étoffera plus loin cette définition, elle suffit bien pour le moment.

Je ne comprends rien. Passe encore qu'une variable en contienne d'autres, après tout les chaînes de caractères contiennent bien des caractères, mais qu'une variable contienne des fonctions… Cela rime à quoi ?

Je pourrais passer des heures à expliquer la théorie du concept que vous n'en seriez pas beaucoup plus avancés. J'ai choisi de vous montrer les objets par l'exemple et donc, vous allez très rapidement voir ce que tout cela signifie. Mais vous allez devoir me faire confiance, au début, sur l'utilité de la méthode objet.

Avant d'attaquer, une petite précision. J'ai dit qu'un objet était un peu comme une variable… en fait, pour être exact, il faut dire qu'une variable est un objet. Toutes les variables avec lesquelles nous avons travaillé jusqu'ici sont des objets. Les fonctions que nous avons vues sont également des objets. En Python, tout est objet : gardez cela à l'esprit.

Les méthodes de la classe str

Oh la la, j'en vois qui grimacent rien qu'en lisant le titre. Vous n'avez pourtant aucune raison de vous inquiéter ! On va y aller tout doucement.

Posons un problème : comment peut-on passer une chaîne de caractères en minuscules ? Si vous n'avez lu jusqu'à présent que les premiers chapitres, vous ne pourrez pas faire cet exercice ; j'ai volontairement évité de trop aborder les chaînes de caractères jusqu'ici. Mais admettons que vous arriviez à coder une fonction prenant en paramètre la chaîne en question. Vous aurez un code qui ressemble à ceci :

>>> chaine = "NE CRIE PAS SI FORT !"
>>> mettre_en_minuscule(chaine)
'ne crie pas si fort !'

Sachez que, dans les anciennes versions de Python, il y avait un module spécialisé dans le traitement des chaînes de caractères. On importait ce module et on pouvait appeler la fonction passant une chaîne en minuscules. Ce module existe d'ailleurs encore et reste utilisé pour certains traitements spécifiques. Mais on va découvrir ici une autre façon de faire. Regardez attentivement :

>>> chaine = "NE CRIE PAS SI FORT !"
>>> chaine.lower() # Mettre la chaîne en minuscule
'ne crie pas si fort !'

La fonction lower est une nouveauté pour vous. Vous devez reconnaître le point « . » qui symbolisait déjà, dans le chapitre sur les modules, une relation d'appartenance (a.b signifiait que b était contenu dans a). Ici, il possède la même signification : la fonction lower est une fonction de la variable chaine.

La fonction lower est propre aux chaînes de caractères. Toutes les chaînes peuvent y faire appel. Si vous tapez type(chaine) dans l'interpréteur, vous obtenez <class 'str'>. Nous avons dit qu'une variable est issue d'un type de donnée. Je vais à présent reformuler : un objet est issu d'une classe. La classe est une forme de type de donnée, sauf qu'elle permet de définir des fonctions et variables propres au type. C'est pour cela que, dans toutes les chaînes de caractères, on peut appeler la fonction lower. C'est tout simplement parce que la fonction lower a été définie dans la classe str. Les fonctions définies dans une classe sont appelées des méthodes.

Récapitulons. Nous avons découvert :

  • Les objets, que j'ai présentés comme des variables, pouvant contenir d'autres variables ou fonctions (que l'on appelle méthodes). On appelle une méthode d'un objet grâce à objet.methode().

  • Les classes, que j'ai présentées comme des types de données. Une classe est un modèle qui servira à construire un objet ; c'est dans la classe qu'on va définir les méthodes propres à l'objet.

Voici le mécanisme qui vous permet d'appeler la méthode lower d'une chaîne :

  1. Les développeurs de Python ont créé la classe str qui est utilisée pour créer des chaînes de caractères. Dans cette classe, ils ont défini plusieurs méthodes, comme lower, qui pourront être utilisées par n'importe quel objet construit sur cette classe.

  2. Quand vous écrivez chaine = "NE CRIE PAS SI FORT !", Python reconnaît qu'il doit créer une chaîne de caractères. Il va donc créer un objet d'après la classe (le modèle) qui a été définie à l'étape précédente.

  3. Vous pouvez ensuite appeler toutes les méthodes de la classe str depuis l'objet chaine que vous venez de créer.

Ouf ! Cela fait beaucoup de choses nouvelles, du vocabulaire et des concepts un peu particuliers.

Vous ne voyez peut-être pas encore tout l'intérêt d'avoir des méthodes définies dans une certaine classe. Cela permet d'abord de bien séparer les diverses fonctionnalités (on ne peut pas passer en minuscules un nombre entier, cela n'a aucun sens). Ensuite, c'est plus intuitif, une fois passé le choc de la première rencontre.

Bon, on parle, on parle, mais on ne code pas beaucoup !

Mettre en forme une chaîne

Non, vous n'allez pas apprendre à mettre une chaîne en gras, souligné, avec une police Verdana de 15px… Nous ne sommes encore que dans une console. Nous venons de présenter lower, il existe d'autres méthodes. Avant tout, voyons un contexte d'utilisation.

Certains d'entre vous se demandent peut-être l'intérêt de passer des chaînes en minuscules… alors voici un petit exemple.

chaine = str() # Crée une chaîne vide
# On aurait obtenu le même résultat en tapant chaine = ""

while chaine.lower() != "q":
    print("Tapez 'Q' pour quitter...")
    chaine = input()

print("Merci !")

Vous devez comprendre rapidement ce programme. Dans une boucle, on demande à l'utilisateur de taper la lettre « q » pour quitter. Tant que l'utilisateur saisit une autre lettre, la boucle continue de s'exécuter. Dès que l'utilisateur appuie sur la touche Q de son clavier, la boucle s'arrête et le programme affiche « Merci ! ». Cela devrait vous rappeler quelque chose… direction le TP de la partie 1 pour ceux qui ont la mémoire courte.

La petite nouveauté réside dans le test de la boucle : chaine.lower() != "q". On prend la chaîne saisie par l'utilisateur, on la passe en minuscules et on regarde si elle est différente de « q ». Cela veut dire que l'utilisateur peut taper « q » en majuscule ou en minuscule, dans les deux cas la boucle s'arrêtera.

Notez que chaine.lower() renvoie la chaîne en minuscules mais ne modifie pas la chaîne. C'est très important, nous verrons pourquoi dans le prochain chapitre.

Notez aussi que nous avons appelé la fonction str pour créer une chaîne vide. Je ne vais pas trop compliquer les choses mais sachez qu'appeler ainsi un type en tant que fonction permet de créer un objet de la classe. Ici, str() crée un objet chaîne de caractères. Nous avons vu dans la première partie le mot-clé int(), qui crée aussi un entier (si nécessaire depuis un autre type, ce qui permet de convertir une chaîne en entier).

Bon, voyons d'autres méthodes. Je vous invite à tester mes exemples (ils sont commentés, mais on retient mieux en essayant par soi-même).

>>> minuscules = "une chaine en minuscules"
>>> minuscules.upper() # Mettre en majuscules
'UNE CHAINE EN MINUSCULES'
>>> minuscule.capitalize() # La première lettre en majuscule
'Une chaine en minuscules'
>>> espaces = "   une  chaine avec  des espaces   "
>>> espaces.strip() # On retire les espaces au début et à la fin de la chaîne
'une  chaine avec  des espaces'
>>> titre = "introduction"
>>> titre.upper().center(20)
'    INTRODUCTION    '
>>>

La dernière instruction mérite quelques explications.

On appelle d'abord la méthode upper de l'objet titre. Cette méthode, comme vous l'avez vu plus haut, renvoie en majuscules la chaîne de caractères contenue dans l'objet.

On appelle ensuite la méthode center, méthode que nous n'avons pas encore vue et qui permet de centrer une chaîne. On lui passe en paramètre la taille de la chaîne que l'on souhaite obtenir. La méthode va ajouter alternativement un espace au début et à la fin de la chaîne, jusqu'à obtenir la longueur demandée. Dans cet exemple, titre contient la chaîne 'introduction', chaîne qui (en minuscules ou en majuscules) mesure 12 caractères. On demande à center de centrer cette chaîne dans un espace de 20 caractères. La méthode center va donc placer 4 espaces avant le titre et 4 espaces après, pour faire 20 caractères en tout.

Bon, mais maintenant, sur quel objet travaille center ? Sur titre ? Non. Sur la chaîne renvoyée par titre.upper(), c'est-à-dire le titre en majuscules. C'est pourquoi on peut « chaîner » ces deux méthodes : upper, comme la plupart des méthodes de chaînes, travaille sur une chaîne et renvoie une chaîne… qui elle aussi va posséder les méthodes propres à une chaîne de caractères. Si ce n'est pas très clair, faites quelques tests, avec titre.upper() et titre.center(20), en passant par une seconde variable si nécessaire, pour vous rendre compte du mécanisme ; ce n'est pas bien compliqué.

Je n'ai mis ici que quelques méthodes, il y en a bien d'autres. Vous pouvez en voir la liste dans l'aide, en tapant, dans l'interpréteur : help(str).

Formater et afficher une chaîne

Attends, on a appris à faire cela depuis cinq bons chapitres ! On ne va pas tout réapprendre quand même ?

Heureusement que non ! Mais nous allons apprendre à considérer ce que nous savons à travers le modèle objet. Et vous allez vous rendre compte que, la plupart du temps, nous n'avons fait qu'effleurer les fonctionnalités du langage.

Je ne vais pas revenir sur ce que j'ai dit, pour afficher une chaîne, on passe par la fonction print.

chaine = "Bonjour tout le monde !"
print(chaine)

Rien de nouveau ici. En revanche, nous allons un peu changer nos habitudes en ce qui concerne l'affichage de plusieurs variables.

Jusqu'ici, nous avons utilisé print en lui imputant plusieurs paramètres. Cela fonctionne mais nous allons voir une méthode légèrement plus souple, qui d'ailleurs n'est pas seulement utile pour l'affichage.

>>> prenom = "Paul"
>>> nom = "Dupont"
>>> age = 21
>>> print("Je m'appelle {0} {1} et j'ai {2} ans.".format(prenom, nom, age))
Je m'appelle Paul Dupont et j'ai 21 ans.

Mais ! C'est quoi cela ?

Question légitime. Voyons un peu.

Première syntaxe de la méthode format

Nous avons utilisé une méthode de la classe str pour formater notre chaîne. De gauche à droite, nous avons :

  • une chaîne de caractères qui ne présente rien de particulier, sauf ces accolades entourant des nombres, d'abord 0, puis 1, puis 2 ;

  • nous appelons la méthode format de cette chaîne en lui passant en paramètres les variables à afficher, dans un ordre bien précis ;

  • quand Python exécute cette méthode, il remplace dans notre chaîne {0} par la première variable passée à la méthode format (soit le prénom), {1} par la deuxième variable… et ainsi de suite.

Bien, mais on aurait pu faire exactement la même chose en passant plusieurs valeurs à print, non ?

Absolument. Mais rappelez-vous que cette fonctionnalité est bien plus puissante qu'un simple affichage, vous pouvez formater des chaînes de cette façon. Ici, nous avons directement affiché la chaîne formatée, mais nous aurions pu la stocker :

>>> nouvelle_chaine = "Je m'appelle {0} {1} et j'ai {2} ans.".format(prenom, nom, age)
>>>

Pour faire la même chose sans utiliser format, on aurait dû concaténer des chaînes, c'est-à-dire les mettre bout à bout en respectant une certaine syntaxe. Nous allons voir cela un peu plus loin mais cette solution reste plus élégante.

Dans cet exemple, nous avons appelé les variables dans l'ordre où nous les placions dans format, mais ce n'est pas une obligation. Considérez cet exemple :

>>> prenom = "Paul"
>>> nom = "Dupont"
>>> age = 21
>>> print( \
...   "Je m'appelle {0} {1} ({3} {0} pour l'administration) et j'ai {2} " \
...   "ans.".format(prenom, nom, age, nom.upper()))
Je m'appelle Paul Dupont (DUPONT Paul pour l'administration) et j'ai 21 ans.

J'ai coupé notre instruction, plutôt longue, à l'aide du signe « \ » placé avant un saut de ligne, pour indiquer à Python que l'instruction se prolongeait au-dessous.

Si vous avez du mal à comprendre l'exemple, relisez l'instruction en remplaçant vous-mêmes les nombres entre accolades par les variables.

>>> date = "Dimanche 24 juillet 2011"
>>> heure = "17:00"
>>> print("Cela s'est produit le {}, à {}.".format(date, heure))
Cela s'est produit le Dimanche 24 juillet 2011, à 17:00.
>>>

Naturellement, cela ne fonctionne que si vous donnez les variables dans le bon ordre dans format.

Cette syntaxe suffit la plupart du temps mais elle n'est pas forcément intuitive quand on insère beaucoup de variables : on doit retenir leur position dans l'appel à format pour comprendre laquelle est affichée à tel endroit. Mais il existe une autre syntaxe.

Seconde syntaxe de la méthode format

On peut également nommer les variables que l'on va afficher, c'est souvent plus intuitif que d'utiliser leur indice. Voici un nouvel exemple :

# formatage d'une adresse
adresse = """
  {no_rue}, {nom_rue}
  {code_postal} {nom_ville} ({pays})"""
  .format(no_rue=5, nom_rue="rue des Postes", code_postal=75003, nom_ville="Paris", pays="France")
print(adresse)

… affichera :

5, rue des Postes
  75003 Paris (France)

Je pense que vous voyez assez précisément en quoi consiste cette deuxième syntaxe de format. Au lieu de donner des nombres entre accolades, on spécifie des noms de variables qui doivent correspondre à ceux fournis comme mots-clés dans la méthode format. Je ne m'attarderai pas davantage sur ce point, je pense qu'il est assez clair comme cela.

La concaténation de chaînes

Nous allons glisser très rapidement sur le concept de concaténation, assez intuitif d'ailleurs. On cherche à regrouper deux chaînes en une, en mettant la seconde à la suite de la première. Cela se fait le plus simplement du monde :

>>> prenom = "Paul"
>>> message = "Bonjour"
>>> chaine_complete = message + prenom # On utilise le symbole '+' pour concaténer deux chaînes
... print(chaine_complete) # Résultat :
BonjourPaul
>>> # Pas encore parfait, il manque un espace
... # Qu'à cela ne tienne !
... chaine_complete = message + " " + prenom
>>> print(chaine_complete) # Résultat :
Bonjour Paul
>>>

C'est assez clair je pense. Le signe « + » utilisé pour ajouter des nombres est ici utilisé pour concaténer deux chaînes. Essayons à présent de concaténer des chaînes et des nombres :

>>> age = 21
>>> message = "J'ai " + age + " ans."
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
>>>

Python se fâche tout rouge ! Certains langages auraient accepté cette syntaxe sans sourciller mais Python n'aime pas cela du tout.

Au début de la première partie, nous avons dit que Python était un langage à typage dynamique, ce qui signifie qu'il identifie lui-même les types de données et que les variables peuvent changer de type au cours du programme. Mais Python est aussi un langage fortement typé, et cela veut dire que les types de données ne sont pas là juste pour faire joli, on ne peut pas les ignorer. Ainsi, on veut ici ajouter une chaîne à un entier et à une autre chaîne. Python ne comprend pas : est-ce que les chaînes contiennent des nombres qu'il doit convertir pour les ajouter à l'entier ou est-ce que l'entier doit être converti en chaîne puis concaténé avec les autres chaînes ? Python ne sait pas. Il ne le fera pas tout seul. Mais il se révèle être de bonne volonté puisqu'il suffit de lui demander de convertir l'entier pour pouvoir le concaténer aux autres chaînes.

>>> age = 21
>>> message = "J'ai " + str(age) + " ans."
>>> print(message)
J'ai 21 ans.
>>>

On appelle str pour convertir un objet en une chaîne de caractères, comme nous avons appelé int pour convertir un objet en entier. C'est le même mécanisme, sauf que convertir un entier en chaîne de caractères ne lèvera vraissemblablement aucune exception.

Le typage fort de Python est important, il est un fondement de sa philosophie. J'ai tendance à considérer qu'un langage faiblement typé crée des erreurs qui sont plus difficiles à repérer alors qu'ici, il nous suffit de convertir explicitement le type pour que Python sache ce qu'il doit faire.

Parcours et sélection de chaînes

Nous avons vu très rapidement dans la première partie un moyen de parcourir des chaînes. Nous allons en voir ici un second qui fonctionne par indice.

Parcours par indice

Vous devez vous en souvenir : j'ai dit qu'une chaîne de caractères était une séquence constituée… de caractères. En fait, une chaîne de caractères est elle-même constituée de chaînes de caractères, chacune d'elles n'étant composée que d'un seul caractère.

Accéder aux caractères d'une chaîne

Nous allons apprendre à accéder aux lettres constituant une chaîne. Par exemple, nous souhaitons sélectionner la première lettre d'une chaîne.

>>> chaine = "Salut les ZER0S !"
>>> chaine[0] # Première lettre de la chaîne
'S'
>>> chaine[2] # Troisième lettre de la chaîne
'l'
>>> chaine[-1] # Dernière lettre de la chaîne
'!'
>>>

On précise entre crochets [] l'indice (la position du caractère auquel on souhaite accéder).

Rappelez-vous, on commence à compter à partir de 0. La première lettre est donc à l'indice 0, la deuxième à l'indice 1, la troisième à l'indice 2… On peut accéder aux lettres en partant de la fin à l'aide d'un indice négatif. Quand vous tapez chaine[-1], vous accédez ainsi à la dernière lettre de la chaîne (enfin, au dernier caractère, qui n'est pas une lettre ici).

On peut obtenir la longueur de la chaîne (le nombre de caractères qu'elle contient) grâce à la fonction len.

>>> chaine = "Salut"
>>> len(chaine)
5
>>>

Pourquoi ne pas avoir défini cette fonction comme une méthode de la classe str ? Pourquoi ne pourrait-on pas faire chaine.len() ?

En fait c'est un peu le cas, mais nous le verrons bien plus loin. str n'est qu'un exemple parmi d'autres de séquences (on en découvrira d'autres dans les prochains chapitres) et donc les développeurs de Python ont préféré créer une fonction qui travaillerait sur les séquences au sens large, plutôt qu'une méthode pour chacune de ces classes.

Méthode de parcours par while

Vous en savez assez pour parcourir une chaîne grâce à la boucle while. Notez que, dans la plupart des cas, on préférera parcourir une séquence avec for. Il est néanmoins bon de savoir procéder de différentes manières, cela vous sera utile parfois.

Voici le code auquel vous pourriez arriver :

chaine = "Salut"
i = 0 # On appelle l'indice 'i' par convention
while i < len(chaine):
    print(chaine[i]) # On affiche le caractère à chaque tour de boucle
    i += 1

N'oubliez pas d'incrémenter i, sinon vous allez avoir quelques surprises.

Si vous essayez d'accéder à un indice qui n'existe pas (par exemple 25 alors que votre chaîne ne fait que 20 caractères de longueur), Python lèvera une exception de type IndexError.

Enfin, une dernière petite chose : vous ne pouvez changer les lettres de la chaîne en utilisant les indices.

>>> mot = "lac"
>>> mot[0] = "b" # On veut remplacer 'l' par 'b'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>>

Python n'est pas content. Il ne veut pas que vous utilisiez les indices pour modifier des caractères de la chaîne. Pour ce faire, il va falloir utiliser la sélection.

Sélection de chaînes

Nous allons voir comment sélectionner une partie de la chaîne. Si je souhaite, par exemple, sélectionner les deux premières lettres de la chaîne, je procéderai comme dans l'exemple ci-dessous.

>>> presentation = "salut"
>>> presentation[0:2] # On sélectionne les deux premières lettres
'sa'
>>> presentation[2:len(presentation)] # On sélectionne la chaîne sauf les deux premières lettres
'lut'
>>>

La sélection consiste donc à extraire une partie de la chaîne. Cette opération renvoie le morceau de la chaîne sélectionné, sans modifier la chaîne d'origine.

Sachez que l'on peut sélectionner du début de la chaîne jusqu'à un indice, ou d'un indice jusqu'à la fin de la chaîne, sans préciser autant d'informations que dans nos exemples. Python comprend très bien si on sous-entend certaines informations.

>>> presentation[:2] # Du début jusqu'à la troisième lettre non comprise
'sa'
>>> presentation[2:] # De la troisième lettre (comprise) à la fin
'lut'
>>>

Maintenant, nous pouvons reprendre notre exemple de tout à l'heure pour constituer une nouvelle chaîne, en remplaçant une lettre par une autre :

>>> mot = "lac"
>>> mot = "b" + mot[1:]
>>> print(mot)
bac
>>>

Voilà !

Cela reste assez peu intuitif, non ?

Pour remplacer des lettres, cela paraît un peu lourd en effet. Et d'ailleurs on s'en sert assez rarement pour cela. Pour rechercher/remplacer, nous avons à notre disposition les méthodes count, find et replace, à savoir « compter », « rechercher » et « remplacer ».

En résumé

  • Les variables utilisées jusqu'ici sont en réalité des objets.

  • Les types de données utilisés jusqu'ici sont en fait des classes. Chaque objet est modelé sur une classe.

  • Chaque classe définit certaines fonctions, appelées méthodes, qui seront accessibles depuis l'objet grâce à objet.methode(arguments).

  • On peut directement accéder à un caractère d'une chaîne grâce au code suivant : chaine[position_dans_la_chaine].

  • Il est tout à fait possible de sélectionner une partie de la chaîne grâce au code suivant : chaine[indice_debut:indice_fin].

Découvrez aussi ce cours en...

Exemple de certificat de réussite
Exemple de certificat de réussite