Fonctions et chaînes : return, f-strings, méthodes de str
Écrire une fonction qui renvoie un résultat, distinguer return de print, utiliser les f-strings et le déballage, et ne plus se faire piéger par les méthodes de str qui renvoient une nouvelle chaîne.
Mis à jour le
Pourquoi on voit ça
Dès qu’un bout de code sert deux fois, on le range dans une fonction : valider un port, fabriquer une adresse, lire une ligne d’inventaire. Et comme presque tout ce qu’un script DevOps lit est du texte (fichiers de config, logs, sorties de commandes), il faut savoir nettoyer et découper des chaînes.
Deux pièges reviennent sans arrêt au contrôle, et tous les deux viennent de la même erreur : croire qu’une valeur a été gardée alors qu’elle a été perdue.
- Une fonction qui fait
printau lieu dereturnrenvoieNone. - Une méthode de
strne modifie jamais la chaîne d’origine.
Définir et appeler une fonction
def url(host, port):
return f"{host}:{port}"
print(url("web-1", 80))
web-1:80
defcrée la fonction. Rien ne s’exécute à ce moment-là.hostetportsont les paramètres : des noms qui recevront les valeurs.- Le corps est décalé de 4 espaces, comme pour un
if. url("web-1", 80)est l’appel : c’est là que le corps s’exécute.
return contre print
Ce sont deux choses différentes :
| Ce que ça fait | Le résultat est réutilisable ? | |
|---|---|---|
print(x) |
affiche x à l’écran, pour un humain |
non |
return x |
renvoie x à celui qui a appelé la fonction |
oui |
Une fonction sans return renvoie None.
def count_web(servers):
n = len(servers)
print(n)
total = count_web(["a", "b"])
print(total)
2
None
Déroule : l’appel affiche 2 (le print dans la fonction). Puis la fonction se termine sans return, donc total reçoit None. Le dernier print affiche None.
Avec return, la valeur revient vraiment :
def count_web(servers):
return len(servers)
total = count_web(["a", "b"])
print(total + 1)
3
Autre chose à savoir : return arrête la fonction. Ce qui est écrit après n’est pas exécuté.
def kind(port):
if port < 1024:
return "système"
return "libre"
print(kind(80))
print(kind(8080))
système
libre
Paramètres par défaut
Un paramètre peut avoir une valeur de secours. Elle sert seulement si l’appel ne donne pas cet argument.
def url(host, port=80):
return f"{host}:{port}"
print(url("web-1"))
print(url("db-1", 5432))
web-1:80
db-1:5432
f-strings
Un f devant les guillemets, et tout ce qui est entre accolades est calculé puis inséré dans le texte. Plus besoin de str() ni de +.
name = "web-1"
port = 80
print(f"{name} écoute sur {port}")
print(f"suivant : {port + 1}")
print("{name}")
web-1 écoute sur 80
suivant : 81
{name}
La dernière ligne montre le piège : sans le f, les accolades sont du texte ordinaire.
Déballage de tuple
Quand il y a plusieurs noms à gauche du =, Python range chaque élément dans une variable, dans l’ordre.
name, port = ("web-1", 80)
print(name)
print(port)
web-1
80
C’est ce qui se passe dans for k, v in s.items() : chaque paire est déballée en k et v. Le déballage marche aussi avec une liste, par exemple le résultat d’un split. Il faut juste autant de noms que d’éléments.
Méthodes de str : l’originale ne change pas
Une méthode est un outil attaché à une valeur, qu’on appelle avec un point : line.strip().
| Méthode | Ce qu’elle renvoie | Exemple | Résultat |
|---|---|---|---|
strip() |
la chaîne sans les espaces au début et à la fin | " db-1 ".strip() |
'db-1' |
split(",") |
une liste de morceaux | "db-1,prod".split(",") |
['db-1', 'prod'] |
"-".join(liste) |
une chaîne : les morceaux collés | "-".join(["web", "1"]) |
'web-1' |
startswith("db") |
True ou False |
"db-1".startswith("db") |
True |
join s’écrit « à l’envers » : c’est le séparateur qui est avant le point, et la liste entre parenthèses.
Le piège : croire que la chaîne a été modifiée
Voici la règle, à connaître par cœur :
Une méthode de
strrenvoie une nouvelle valeur. La chaîne d’origine ne change jamais.
line = " db-1 "
line.strip()
print(len(line))
8
line.strip() a bien fabriqué "db-1". Mais ce résultat n’a été rangé nulle part : il est perdu. line contient toujours ses 8 caractères, espaces compris.
C’est exactement le même réflexe que pour int(port) dans la leçon sur les types, et que pour return plus haut : seul = change une variable. Pour garder le résultat, il y a deux façons.
line = " db-1 "
clean = line.strip()
print(len(clean), len(line))
line = line.strip()
print(len(line))
4 8
4
clean = line.strip(): le résultat va dans une nouvelle variable,linereste intacte.line = line.strip(): on remplace le contenu delinepar le résultat.
Enchaîner les méthodes
On peut enchaîner : chaque méthode travaille sur le résultat de la précédente. Mais la variable de départ, elle, ne bouge toujours pas.
line = " db-1,prod "
parts = line.strip().split(",")
print(parts)
print(line.startswith("db"))
['db-1', 'prod']
False
parts est correct, parce que le résultat de la chaîne d’appels a été rangé avec =. Mais line commence toujours par deux espaces, donc line.startswith("db") vaut False.
Au contrôle, pose-toi la question pour chaque ligne : y a-t-il un = ? Si non, la variable a exactement la même valeur qu’à la ligne d’avant.
À retenir
printaffiche,returnrenvoie. Une fonction sansreturnrenvoieNone.returnarrête la fonction.- Un paramètre par défaut (
port=80) ne sert que si l’appel ne donne pas l’argument. - f-string :
f"{name}:{port}". Sans lef, les accolades restent du texte. strip,split,join,startswithrenvoient un résultat. La chaîne d’origine ne change jamais.- Pas de
=, pas de changement : pour garder un résultat, écrisline = line.strip().
Entraînement
12 questions, dont 6 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.
Ta note
Cartes · 9
Réviser les cartes ici
Pourquoi