Tom Daluzeau
← Parcours Python
Python · leçon 4 / 5Ch. 1 · Bases12 minTerminée

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.

  1. Une fonction qui fait print au lieu de return renvoie None.
  2. Une méthode de str ne 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
  • def crée la fonction. Rien ne s’exécute à ce moment-là.
  • host et port sont 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
l'appelant la fonction l'écran total = None print(n) 2 print montre la valeur à un humain ; l'appelant ne reçoit rien (None) total = 2 return n rien ne s'affiche return renvoie la valeur à l'appelant, qui peut la réutiliser
print va vers l'écran, return revient vers celui qui a appelé la fonction.

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.

"db-1,prod" split(",") une liste de deux morceaux 'db-1' 'prod' name = 'db-1' env = 'prod' 1er morceau → 1er nom 2e morceau → 2e nom il faut autant de noms à gauche du = que de morceaux
name, env = "db-1,prod".split(",") : chaque morceau va dans un nom, dans l'ordre.

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 str renvoie 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, line reste intacte.
  • line = line.strip() : on remplace le contenu de line par le résultat.
line " db-1 " 8 caractères, ne change pas .strip() nouvelle chaîne "db-1" line.strip() pas de = : résultat perdu clean = line.strip() avec = : résultat gardé
Une méthode de str fabrique une nouvelle chaîne. Seul = la range quelque part.

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

  • print affiche, return renvoie. Une fonction sans return renvoie None.
  • return arrê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 le f, les accolades restent du texte.
  • strip, split, join, startswith renvoient un résultat. La chaîne d’origine ne change jamais.
  • Pas de =, pas de changement : pour garder un résultat, écris line = line.strip().

Entraînement

12 questions, dont 6 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.

Cartes · 9

Réviser les cartes ici

Espace : retourner