J'ai une question à propose du comportement de Python sur la façon de créer des objets et de les référencer.
Situation 1 :a = 5
b = 5Truea is b
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet qui doit déjà exister (j'imagine que c'est un objet assez courant, utilisé par Python, qui est créé à son lancement et qu'il doit même être déjà référencé), il n'est pas créé donc a va référencer l'objet 5 déjà existant. Ensuite quand je fais b = 5, il se passe la même chose et b va référencer le même objet 5 déjà existant. Du coup, a et b référencent le même objet, ce qui explique que a is b renvoie True.
Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :Falsea = 500
b = 500
a is b
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà (il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait donc pas être créé et b devrait référencer là encore le même objet 500 déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas le cas.
Où mon raisonnement est-il faux ?
a = 255
b = 255
a is b
a = 256
b = 256
a is b
a = 257
b = 257
a is b
a = 257; b = 257; a is b
a = 257
b = 257
a is b
J'ai une question à propose du comportement de Python sur la façon de créer des objets et de les référencer.
Situation 1 :
>>> a = 5
>>> b = 5
>>> a is b
True
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet qui doit déjà exister (j'imagine que c'est un objet assez courant, utilisé par Python, qui est créé à son lancement et qu'il doit même être déjà référencé), il n'est pas créé donc a va référencer l'objet 5 déjà existant. Ensuite quand je fais b = 5, il se passe la même chose et b va référencer le même objet 5 déjà existant. Du coup, a et b référencent le même objet, ce qui explique que a is b renvoie True.
Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :
>>> a = 500
>>> b = 500
>>> a is b
False
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà (il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait donc pas être créé et b devrait référencer là encore le même objet 500 déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas le cas.
Où mon raisonnement est-il faux ?
a = 255
b = 255
a is b
a = 256
b = 256
a is b
a = 257
b = 257
a is b
a = 257; b = 257; a is b
a = 257
b = 257
a is b
J'ai une question à propose du comportement de Python sur la façon de créer des objets et de les référencer.
Situation 1 :a = 5
b = 5Truea is b
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet qui doit déjà exister (j'imagine que c'est un objet assez courant, utilisé par Python, qui est créé à son lancement et qu'il doit même être déjà référencé), il n'est pas créé donc a va référencer l'objet 5 déjà existant. Ensuite quand je fais b = 5, il se passe la même chose et b va référencer le même objet 5 déjà existant. Du coup, a et b référencent le même objet, ce qui explique que a is b renvoie True.
Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :Falsea = 500
b = 500
a is b
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà (il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait donc pas être créé et b devrait référencer là encore le même objet 500 déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas le cas.
Où mon raisonnement est-il faux ?
a = 255
b = 255
a is b
a = 256
b = 256
a is b
a = 257
b = 257
a is b
a = 257; b = 257; a is b
a = 257
b = 257
a is b
Hello,
On 5/10/20 11:39 AM, thomas wrote:J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :
>>> a = 5
>>> b = 5
>>> a is b
True
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet
qui doit déjà exister (j'imagine que c'est un objet assez courant,
utilisé par Python, qui est créé à son lancement et qu'il doit même
être déjà référencé), il n'est pas créé donc a va référencer l'objet 5
déjà existant. Ensuite quand je fais b = 5, il se passe la même chose
et b va référencer le même objet 5 déjà existant. Du coup, a et b
référencent le même objet, ce qui explique que a is b renvoie True.
Perso, de ce petit test, je pense qu'on ne peut pas affirmer que l'objet
« 5 »
existait avant même l'instruction « a = 5 » (même si c'est peut-être
tout à fait vrai.
On peut juste dire qu'effectivement, au moment de « b = 5 »,
Python a
fait pointer b vers l'objet « 5 » référencé par la variable a et on peut
penser que c'est dans un souci d'optimisation de la mémoire.
Et, au passage, cette
référence du même objet entre a et b est possible car l'objet référencé
« 5 »
est immutable. Cela ne pourrait pas se produire avec par exemple :
a = []
b = []
a is b # => renverra forcément False.
vu que [] n'est pas un objet immutable, il est mutable. En effet, rien
dans le
code n'indique explicitement que a et b référencent le même objet. Donc
il n'y
a aucune raison pour qu'une modification de l'objet référencé par a modifie
l'état de l'objet référencé par b. Donc a et b sont nécessairement deux
objets
distincts de la mémoire.
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = <expression littérale d'un objet>
b = <la même expression littérale que dans la ligne précédente>
1. Ou bien l'expression littérale correspond à un objet mutable et dans
ce cas
tu auras forcément a et b qui référencent des objets distincts dans
la mémoire
(j'ai tenté d'expliquer ci-dessus pourquoi).
2. Ou bien l'expression littérale correspond à un objet immutable et là :
a. Ou bien Python arrive à être « malin » et alors a et b vont
référencer le
même objet. Tant mieux. Rien dans ton code n'indique de lien
entre a et b
et donc on souhaite qu'un changement d'état de l'objet référencé
par a
n'ait aucune incidence sur l'objet référencé par b. Mais ceci ne
se produira
jamais vu que l'objet référencé par a (et par b) est non
modifiable. La
seule chose que tu pourras faire, c'est faire en sorte a et b
référencent
un nouvel objet et là ce sera une autre histoire. Donc Python
peut faire
cette optimisation mémoire dans ce cas là sans incidence logique
sur le code.
b. Ou bien il n'est pas assez « malin » et alors a et b vont
référencer deux objets
distincts dans la mémoire qui sont pourtant chacun immutables et
rigoureusement
identiques. Une optimisation de la mémoire loupé, tant pis...
Qu'on soit dans le cas 2a ou 2b, c'est un détail d'implémentation pour
toi le programmeur.
Rien n'oblige Python à être dans le cas 2b (où il est malin) à chaque
fois.
Pour toi le programmeur, ça ne changera rien dans le comportement de ton code.
Après, si tu (toi le programmeur) veux absolument que a et b référence
le même objet,
charge à toi de le dire _explicitement_ à Python avec ce code là :
a = <expression littérale d'un objet, immuable ou pas, on s'en
fiche ici>
b = a
Là, tu auras la garantie d'avoir « (a is b) == True ». Finalement, on
reste bien dans
la philosophie Python du « explicit is better than implicit ». ;)Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :
>>> a = 500
>>> b = 500
>>> a is b
False
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis
référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà
(il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait
donc pas être créé et b devrait référencer là encore le même objet 500
déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas
le cas.
Où mon raisonnement est-il faux ?
Je pense que tu as tous les éléments dans ce que j'ai dit ci-dessus.
Et, histoire de mettre encore un peu plus la pagaille, voici ce que
j'observe
sur Python 3.6.9 issu de ma distribution Ubuntu 18.04.
Déjà, je constate comme toi, et je constate que ça commence à partir de
l'entier 257 :
#--------------------------------a = 255
b = 255
a is b
Truea = 256
b = 256
a is b
Truea = 257
b = 257
a is b
False
#--------------------------------
Maintenant, regarde ce truc rigolo :
#--------------------------------a = 257; b = 257; a is b
Truea = 257
b = 257
a is b
False
#--------------------------------
Si je mets les instructions sur une seule ligne, j'ai bien « (a is b) ==
True ».
Tu vois bien qu'on est vraiment dans du détail d'implémentation.
Et, pour enfoncer le clou, j'ai un comportement différent quand c'est
exécuté dans un script :
#--------------------------------
~$ cat /tmp/test.py
#!/usr/bin/env python3
a = 500
b = 500
x = (a is b)
print(x)
~$ /tmp/test.py
True
#--------------------------------
Encore une fois, tout ceci n'est pas si important. Ce qu'il est
important de comprendre
ce que rien n'oblige Python à faire en sorte que deux variables a et b
référencent le
même objet sauf si tu lui demandes explicitement avec quelque chose comme :
a = ...
b = a
Sans cette demande explicite de ta part, Python pourra être amené,
éventuellement, à faire
en sorte que a et b référencent chacun le même objet, mais à la
condition nécessaire (et
non suffisante) que celui-ci soit immutable et encore il ne fera pas à
chaque fois (quand
est-ce qu'il le fera relève du détail d'implémentation).
Voilà. J'espère que c'est un peu plus clair pour toi.
À+
Hello,
On 5/10/20 11:39 AM, thomas wrote:
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :
>>> a = 5
>>> b = 5
>>> a is b
True
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet
qui doit déjà exister (j'imagine que c'est un objet assez courant,
utilisé par Python, qui est créé à son lancement et qu'il doit même
être déjà référencé), il n'est pas créé donc a va référencer l'objet 5
déjà existant. Ensuite quand je fais b = 5, il se passe la même chose
et b va référencer le même objet 5 déjà existant. Du coup, a et b
référencent le même objet, ce qui explique que a is b renvoie True.
Perso, de ce petit test, je pense qu'on ne peut pas affirmer que l'objet
« 5 »
existait avant même l'instruction « a = 5 » (même si c'est peut-être
tout à fait vrai.
On peut juste dire qu'effectivement, au moment de « b = 5 »,
Python a
fait pointer b vers l'objet « 5 » référencé par la variable a et on peut
penser que c'est dans un souci d'optimisation de la mémoire.
Et, au passage, cette
référence du même objet entre a et b est possible car l'objet référencé
« 5 »
est immutable. Cela ne pourrait pas se produire avec par exemple :
a = []
b = []
a is b # => renverra forcément False.
vu que [] n'est pas un objet immutable, il est mutable. En effet, rien
dans le
code n'indique explicitement que a et b référencent le même objet. Donc
il n'y
a aucune raison pour qu'une modification de l'objet référencé par a modifie
l'état de l'objet référencé par b. Donc a et b sont nécessairement deux
objets
distincts de la mémoire.
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = <expression littérale d'un objet>
b = <la même expression littérale que dans la ligne précédente>
1. Ou bien l'expression littérale correspond à un objet mutable et dans
ce cas
tu auras forcément a et b qui référencent des objets distincts dans
la mémoire
(j'ai tenté d'expliquer ci-dessus pourquoi).
2. Ou bien l'expression littérale correspond à un objet immutable et là :
a. Ou bien Python arrive à être « malin » et alors a et b vont
référencer le
même objet. Tant mieux. Rien dans ton code n'indique de lien
entre a et b
et donc on souhaite qu'un changement d'état de l'objet référencé
par a
n'ait aucune incidence sur l'objet référencé par b. Mais ceci ne
se produira
jamais vu que l'objet référencé par a (et par b) est non
modifiable. La
seule chose que tu pourras faire, c'est faire en sorte a et b
référencent
un nouvel objet et là ce sera une autre histoire. Donc Python
peut faire
cette optimisation mémoire dans ce cas là sans incidence logique
sur le code.
b. Ou bien il n'est pas assez « malin » et alors a et b vont
référencer deux objets
distincts dans la mémoire qui sont pourtant chacun immutables et
rigoureusement
identiques. Une optimisation de la mémoire loupé, tant pis...
Qu'on soit dans le cas 2a ou 2b, c'est un détail d'implémentation pour
toi le programmeur.
Rien n'oblige Python à être dans le cas 2b (où il est malin) à chaque
fois.
Pour toi le programmeur, ça ne changera rien dans le comportement de ton code.
Après, si tu (toi le programmeur) veux absolument que a et b référence
le même objet,
charge à toi de le dire _explicitement_ à Python avec ce code là :
a = <expression littérale d'un objet, immuable ou pas, on s'en
fiche ici>
b = a
Là, tu auras la garantie d'avoir « (a is b) == True ». Finalement, on
reste bien dans
la philosophie Python du « explicit is better than implicit ». ;)
Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :
>>> a = 500
>>> b = 500
>>> a is b
False
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis
référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà
(il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait
donc pas être créé et b devrait référencer là encore le même objet 500
déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas
le cas.
Où mon raisonnement est-il faux ?
Je pense que tu as tous les éléments dans ce que j'ai dit ci-dessus.
Et, histoire de mettre encore un peu plus la pagaille, voici ce que
j'observe
sur Python 3.6.9 issu de ma distribution Ubuntu 18.04.
Déjà, je constate comme toi, et je constate que ça commence à partir de
l'entier 257 :
#--------------------------------
a = 255
b = 255
a is b
True
a = 256
b = 256
a is b
True
a = 257
b = 257
a is b
False
#--------------------------------
Maintenant, regarde ce truc rigolo :
#--------------------------------
a = 257; b = 257; a is b
True
a = 257
b = 257
a is b
False
#--------------------------------
Si je mets les instructions sur une seule ligne, j'ai bien « (a is b) ==
True ».
Tu vois bien qu'on est vraiment dans du détail d'implémentation.
Et, pour enfoncer le clou, j'ai un comportement différent quand c'est
exécuté dans un script :
#--------------------------------
~$ cat /tmp/test.py
#!/usr/bin/env python3
a = 500
b = 500
x = (a is b)
print(x)
~$ /tmp/test.py
True
#--------------------------------
Encore une fois, tout ceci n'est pas si important. Ce qu'il est
important de comprendre
ce que rien n'oblige Python à faire en sorte que deux variables a et b
référencent le
même objet sauf si tu lui demandes explicitement avec quelque chose comme :
a = ...
b = a
Sans cette demande explicite de ta part, Python pourra être amené,
éventuellement, à faire
en sorte que a et b référencent chacun le même objet, mais à la
condition nécessaire (et
non suffisante) que celui-ci soit immutable et encore il ne fera pas à
chaque fois (quand
est-ce qu'il le fera relève du détail d'implémentation).
Voilà. J'espère que c'est un peu plus clair pour toi.
À+
Hello,
On 5/10/20 11:39 AM, thomas wrote:J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :
>>> a = 5
>>> b = 5
>>> a is b
True
Jusque-là je me dis que lorsque je fais a = 5, comme c'est un objet
qui doit déjà exister (j'imagine que c'est un objet assez courant,
utilisé par Python, qui est créé à son lancement et qu'il doit même
être déjà référencé), il n'est pas créé donc a va référencer l'objet 5
déjà existant. Ensuite quand je fais b = 5, il se passe la même chose
et b va référencer le même objet 5 déjà existant. Du coup, a et b
référencent le même objet, ce qui explique que a is b renvoie True.
Perso, de ce petit test, je pense qu'on ne peut pas affirmer que l'objet
« 5 »
existait avant même l'instruction « a = 5 » (même si c'est peut-être
tout à fait vrai.
On peut juste dire qu'effectivement, au moment de « b = 5 »,
Python a
fait pointer b vers l'objet « 5 » référencé par la variable a et on peut
penser que c'est dans un souci d'optimisation de la mémoire.
Et, au passage, cette
référence du même objet entre a et b est possible car l'objet référencé
« 5 »
est immutable. Cela ne pourrait pas se produire avec par exemple :
a = []
b = []
a is b # => renverra forcément False.
vu que [] n'est pas un objet immutable, il est mutable. En effet, rien
dans le
code n'indique explicitement que a et b référencent le même objet. Donc
il n'y
a aucune raison pour qu'une modification de l'objet référencé par a modifie
l'état de l'objet référencé par b. Donc a et b sont nécessairement deux
objets
distincts de la mémoire.
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = <expression littérale d'un objet>
b = <la même expression littérale que dans la ligne précédente>
1. Ou bien l'expression littérale correspond à un objet mutable et dans
ce cas
tu auras forcément a et b qui référencent des objets distincts dans
la mémoire
(j'ai tenté d'expliquer ci-dessus pourquoi).
2. Ou bien l'expression littérale correspond à un objet immutable et là :
a. Ou bien Python arrive à être « malin » et alors a et b vont
référencer le
même objet. Tant mieux. Rien dans ton code n'indique de lien
entre a et b
et donc on souhaite qu'un changement d'état de l'objet référencé
par a
n'ait aucune incidence sur l'objet référencé par b. Mais ceci ne
se produira
jamais vu que l'objet référencé par a (et par b) est non
modifiable. La
seule chose que tu pourras faire, c'est faire en sorte a et b
référencent
un nouvel objet et là ce sera une autre histoire. Donc Python
peut faire
cette optimisation mémoire dans ce cas là sans incidence logique
sur le code.
b. Ou bien il n'est pas assez « malin » et alors a et b vont
référencer deux objets
distincts dans la mémoire qui sont pourtant chacun immutables et
rigoureusement
identiques. Une optimisation de la mémoire loupé, tant pis...
Qu'on soit dans le cas 2a ou 2b, c'est un détail d'implémentation pour
toi le programmeur.
Rien n'oblige Python à être dans le cas 2b (où il est malin) à chaque
fois.
Pour toi le programmeur, ça ne changera rien dans le comportement de ton code.
Après, si tu (toi le programmeur) veux absolument que a et b référence
le même objet,
charge à toi de le dire _explicitement_ à Python avec ce code là :
a = <expression littérale d'un objet, immuable ou pas, on s'en
fiche ici>
b = a
Là, tu auras la garantie d'avoir « (a is b) == True ». Finalement, on
reste bien dans
la philosophie Python du « explicit is better than implicit ». ;)Par contre, ce que je ne comprends pas c'est la chose suivante :
Situation 2 :
>>> a = 500
>>> b = 500
>>> a is b
False
Lorsque je fais a = 500, si l'objet 500 n'existe pas, il est créé puis
référencé par a. Ensuite en faisant b = 500, l'objet 500 existant déjà
(il a, au pire, été créé en faisant a = 500), l'objet 500 ne devrait
donc pas être créé et b devrait référencer là encore le même objet 500
déjà existant. Du coup a is b devrait renvoyer True mais ce n'est pas
le cas.
Où mon raisonnement est-il faux ?
Je pense que tu as tous les éléments dans ce que j'ai dit ci-dessus.
Et, histoire de mettre encore un peu plus la pagaille, voici ce que
j'observe
sur Python 3.6.9 issu de ma distribution Ubuntu 18.04.
Déjà, je constate comme toi, et je constate que ça commence à partir de
l'entier 257 :
#--------------------------------a = 255
b = 255
a is b
Truea = 256
b = 256
a is b
Truea = 257
b = 257
a is b
False
#--------------------------------
Maintenant, regarde ce truc rigolo :
#--------------------------------a = 257; b = 257; a is b
Truea = 257
b = 257
a is b
False
#--------------------------------
Si je mets les instructions sur une seule ligne, j'ai bien « (a is b) ==
True ».
Tu vois bien qu'on est vraiment dans du détail d'implémentation.
Et, pour enfoncer le clou, j'ai un comportement différent quand c'est
exécuté dans un script :
#--------------------------------
~$ cat /tmp/test.py
#!/usr/bin/env python3
a = 500
b = 500
x = (a is b)
print(x)
~$ /tmp/test.py
True
#--------------------------------
Encore une fois, tout ceci n'est pas si important. Ce qu'il est
important de comprendre
ce que rien n'oblige Python à faire en sorte que deux variables a et b
référencent le
même objet sauf si tu lui demandes explicitement avec quelque chose comme :
a = ...
b = a
Sans cette demande explicite de ta part, Python pourra être amené,
éventuellement, à faire
en sorte que a et b référencent chacun le même objet, mais à la
condition nécessaire (et
non suffisante) que celui-ci soit immutable et encore il ne fera pas à
chaque fois (quand
est-ce qu'il le fera relève du détail d'implémentation).
Voilà. J'espère que c'est un peu plus clair pour toi.
À+
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :a = 5
b = 5Truea is b
[...]
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :
>>> a = 5
>>> b = 5
>>> a is b
True
[...]
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :a = 5
b = 5Truea is b
[...]
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :a = 5
b = 5a is b
True
[...]
Bonjour,
Voir par exemple ce lien pour une explication détaillée :
https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :
a = 5
b = 5
a is b
True
[...]
Bonjour,
Voir par exemple ce lien pour une explication détaillée :
https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers
J'ai une question à propose du comportement de Python sur la façon de
créer des objets et de les référencer.
Situation 1 :a = 5
b = 5a is b
True
[...]
Bonjour,
Voir par exemple ce lien pour une explication détaillée :
https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = 500
b = 500
a is b
a = 500
b = 500
a is b
a = 500
b = 500
a is b
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = 500
b = 500
a is b
a = 500
b = 500
a is b
a = 500
b = 500
a is b
Mais tout ceci relève du détail d'implémentation à mon avis et il ne
faut pas
trop s'embêter avec cela. Personnellement, je retiens juste ceci : quand
on a :
a = 500
b = 500
a is b
a = 500
b = 500
a is b
a = 500
b = 500
a is b