Paramètres d'une fonction☘
Un paramètre d'une fonction est une variable locale à cette fonction.☘
On le constate avec:
1 2 3 4 5 6 7 | def f(a, b): c = 42 print("f : locals:", locals()) f(666, 'coucou') |
donne:
1 | f : locals: {'a': 666, 'b': 'coucou', 'c': 42} |
Exercice 1☘
Avec le code suivant:
1 2 3 4 5 6 7 8 9 10 11 | def f(n, t): print("Identifiant de n: ", id(n)) print("Identifiant de t: ", id(t)) m = 1515 tab = [42, 666, 777, 2048] print("Identifiant de m: ", id(m)) print(f"Identifiant de tab: ", id(tab)) f(m, tab) |
Qu'obtient-on? Expliquer.
une réponse
On obtient (vous pouvez obtenir d'autres valeurs, l'important est d'observer celles qui sont identiques):
1 2 3 4 | Identifiant de m: 140638888176368. Identifiant de tab: 140638888411016. Identifiant de n: 140638888176368. Identifiant de t: 140638888411016. |
L'identifiant de n est celui de m. L'identifiant de t est celui de tab.
Interprétation.
- On crée d'abord (lignes 7 et 8) des variables m et tab (externes à f).
- Puis, lors de l'appel
f(m, tab)
, des variables n et t locales à f sont créées avecn = m
ett = tab
.
Exercice 2☘
Quel affichage obtiendra-t-on avec le code ci-dessous? Expliquer.
1 2 3 4 5 6 7 8 | def f(tab): tab[0] = 42 t = [43, 777] f(t) print(t) |
une réponse
On obtient:
1 | [42, 777] |
Nous avons vu en effet que l'appel f(t) se traduisait par la création d'une étiquette locale
à f désignant le même objet que l'argument d'appel (tab = t
).
Comme tab[0] = 42
agit en place (sans créer de nouvel objet, en agissant sur l'objet ciblé),
la variable t externe est bien modifiée.
Exercice 3☘
Quel affichage obtiendra-t-on avec le code ci-dessous? Expliquer.
1 2 3 4 5 6 7 8 | def f(tab): tab.append(666) t = [43, 777] f(t) print(t) |
une réponse
On obtient:
1 | [43, 777, 666] |
Nous avons vu en effet que l'appel f(t) se traduisait par la création d'une étiquette locale
à f désignant le même objet que l'argument d'appel (tab = t
).
Comme tab.append(666)
agit en place (sans créer de nouvel objet, en agissant sur l'objet ciblé),
la variable t externe est bien modifiée.
Exercice 4☘
Quel affichage obtiendra-t-on avec le code ci-dessous? Expliquer.
1 2 3 4 5 6 7 8 | def f(tab): tab = tab + [666] t = [43, 777] f(t) print(t) |
une réponse
On obtient:
1 | [43, 777] |
Nous avons vu en effet que l'appel f(t) se traduisait par la création d'une étiquette locale
à f désignant le même objet que l'argument d'appel (tab = t
).
Mais l'affectation tab = tab + [666]
crée un nouvel objet liste, distinct de celui ciblé par t.
En fin de fonction f, on aura tab = [43, 777, 666]
mais en sortie de fonction, cette variable locale est oubliée
et la variable t externe est inchangée.
Exercice 5☘
Quel affichage obtient-on avec le code suivant:
1 2 3 4 5 6 7 | def f(a): a = 666 a = 42 f(a) print(a) |
une réponse
On obtient:
1 | 42 |
Pour analyser le déroulement, il faut bien comprendre que c'est exactement le même déroulement que pour le code suivant:
1 2 3 4 5 6 7 | def f(b): b = 666 a = 42 f(a) print(a) |
Le paramètre est en effet une variable locale à f. Même s'il se nomme comme la variable externe, c'est une autre variable dans f. Dans la première version, on a donc un a_{\text{externe}} et un a_f interne à f.
On comprend ainsi que le déroulement de f n'ait aucun effet sur la variable a externe.
Au moment de l'appel (on appelle b le paramètre pour clarifier, sinon considérer que vous avez deux étiquettes a mais vivant dans un "monde" différent), nous avons:
puis on exécute la ligne b = 666
(création d'un nouvel objet int):
En sortie de fonction (disparition de la variable locale b), nous nous retrouvons dans la situation:
Important
On retiendra qu'il n'est pas heureux de nommer un paramètre de la même façon que la variable utilisée lors de l'appel: cela ne sert à rien (l'effet est le même qu'en nommant le paramètre par un autre nom) et ne fait que gêner la lecture.