Typage dynamique et affectation
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectifs
Connaître la notion de typage dynamique ;
Connaître le comportement de l'assignation pour Python et JavaScript.
Mise en situation
On peut distinguer différentes manières de typer les variables selon les langages. Certains langages ont un typage statique, d'autre un typage dynamique. Cela signifie que les premiers ne permettent pas de changer le type d'une variable après sa déclaration. C'est souvent le cas des langages de bas niveau, qui sont proches de la machine et de sa gestion mémoire. Les langages à typage dynamique sont eux beaucoup plus flexibles, ils permettent de changer le type d'une variable tout au long de l'exécution.
Rappel : JavaScript et Python : des langages au typage dynamique
JavaScript et Python sont des langages au typage dynamique : les variables peuvent changer de valeurs même si celles-ci ont un type différent. Dans ce cadre, les types sont portés par les valeurs et non les variables.
Exemple : Typage dynamique
Ici, a
est une variable qui change de type pour passer d'un entier à une chaîne de caractères.
a = 42
a = 'fezfe'
Rappel : Type primitif
Les types primitifs sont les types de valeurs les plus simples qui ne contiennent qu'une information atomique.
Exemple : Types primitifs en Python et JavaScript
Il y a quatre types primitifs communs à Python et JavaScript :
les entiers,
les flottants,
les chaînes de caractères,
les booléens.
Complément :
En JavaScript il y a trois autres types primitifs :
les BigInt,
les symboles,
le type
undefined
.
Rappel : Type composé
Les types composés sont des types construits sur un ensemble de types primitifs, comme les listes, les tableaux ou les objets.
Exemple : Types composés en JavaScript
En JavaScript par exemple, deux exemples de types composés sont :
les tableaux :
[]
les objets (enregistrements) :
{}
Fondamental : Comportement de l'assignation pour le typage dynamique
Lorsque l'on assigne une variable en utilisant une autre dans des langages au typage dynamique comme (Python, ou JavaScript), on ne copie pas la valeur : on copie une référence vers cette valeur.
Cette subtilité a des implications très fortes lorsque l'on traite avec des types composés.
Syntaxe : Tester le référencement d'une valeur par deux variables en JavaScript
En JavaScript, l'opérateur d'égalité permet de vérifier que deux variables référencent la même valeur ou non.
Exemple :
let quine = 10000
let bonus = quine
console.log('Equalité:', quine === bonus)
let loto = [100000]
let listeNumero = loto
console.log('Equalité:', loto === listeNumero)
On obtient :
Equalité: true
Equalité: true

Syntaxe : Tester le référencement d'une valeur par deux variables en Python
En Python la fonction id
retourne l'identité de l'objet Python stockant la valeur sous-jacente.
Ainsi, avec l'opérateur d'égalité sur ces identités, on peut vérifier que deux variables référencent la même valeur ou non.
Exemple : Affectation en Python
quine = 10000
bonus = quine
print('ID de quine:', id(quine))
print('ID de bonus:', id(bonus))
print('Equalité:', id(a) == id(b))
loto = [100000]
listeNumero = loto
print('ID de loto:', id(loto))
print('ID de listeNumero:', id(listeNumero))
print('Equalité:', id(loto) == id(listeNumero))
On obtient :
ID de quine: 140510876310096
ID de bonus: 140510876310096
Equalité: True
ID de loto: 140080656991808
ID de listeNumero: 140080656991808
Equalité: True
La subtilité est que quine
et bonus
ne contiennent pas tous les deux une copie de la valeur 10000, mais ils référencent la même case mémoire, qui contient la valeur 10000.
Fondamental : Comportement de la modification de valeur
Lorsque l'on modifie une valeur en JavaScript ou en Python à partir d'une variable :
S'il s'agit d'un type primitif, la valeur est copiée puis modifiée. En d'autres termes, la référence change.
S'il s'agit d'un type composé, on ne change pas de référence : seules les références de valeurs du type composés sont modifiées, s'il s'agit de types primitifs. Sinon, la même règle s'applique, et ainsi de suite.
Exemple : Modification d'un entier en Python
En exécutant cela :
quine = 10000
bonus = quine
print('ID de quine:', id(quine))
print('ID de bonus:', id(bonus))
print('Equalité:', id(quine) == id(bonus))
bonus = bonus + 1
print('ID de quine:', id(quine))
print('ID de bonus:', id(bonus))
print('Equalité:', id(quine) == id(bonus))
On obtient :
ID de quine: 140713190459984
ID de bonus: 140713190459984
Equalité: True
ID de quine: 140713190459984
ID de bonus: 140713190459888
Equalité: False
Ce qui montre que dans le cas de modification d'une valeur de type primitif, l'identité (la référence) change.
Exemple : Modification d'un entier en JavaScript
Le comportement est similaire en JavaScript :
let quine = 10000
let bonus = quine
console.log('Equalité:', quine === bonus)
bonus = bonus + 1
console.log('Equalité:', quine === bonus)
On obtient :
Equalité: true
Equalité: false

Exemple : Modification d'un tableau en Python
En exécutant :
loto = [100000]
listeNumero = loto
print('ID de loto:', id(loto))
print('ID de listeNumero:', id(listeNumero))
print('Equalité:', id(loto) == id(listeNumero))
listeNumero.append(4240142)
print('ID de loto:', id(loto))
print('ID de listeNumero:', id(listeNumero))
print('Equalité:', id(loto) == id(listeNumero))
On obtient :
ID de loto: 140713190902976
ID de listeNumero: 140713190902976
Equalité: True
ID de loto: 140713190902976
ID de listeNumero: 140713190902976
Equalité: True
Ce qui montre que dans le cas de modification d'une valeur de type composé, la référence ne change pas.
Notez que le comportement peut surprendre, car le contenu loto
est modifié au même titre que le contenu listeNumero
, car les variables référencent le même contenu : aucune copie n'est effectuée.
Exemple : Modification d'un tableau en JavaScript
Le résultat est similaire en JavaScript :
let loto = [100000]
let listeNumero = loto
console.log('Equalité:', loto === listeNumero)
listeNumero.push(4240142)
console.log('Equalité:', loto === listeNumero)
On obtient :
Equalité: true
Equalité: true

À retenir
Lors d'une affectation, on assigne des références et non des valeurs aux variables. Si on modifie une valeur à travers une variable, seules les références des variables de types primitifs sont modifiées.
Il ne suffit donc pas de faire une affectation pour copier un type composé : la variable originale et la nouvelle variable référenceront la même valeur (tableau, enregistrement, etc.), et les modifications seront reflétées pour les deux variables.
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.