>>> v = 'TEST'
>>> if not v is 'TEST':
... print "v est different de 'TEST'"
... else:
... print "v est egal a 'TEST'"
...
v est egal a 'TEST'
>>>
>>>
>>> v = 'N/A'
>>> if not v is 'N/A':
... print "v est different de 'N/A'"
... else:
... print "v est egal a 'N/A'"
...
v est different de 'N/A'
>>>
>>> v != 'N/A'
False
J'avoue que je ne comprend pas très bien le fonctionnement de
l'opérateur 'is' dans ces tests.
Manifestement le caractère '/' modifie son comportement
Curieusement, je n'avais encore jamais été confronté à cette situation.
Si quelqu'un a une explication, je suis preneur
Ceci étant dit, l'opérateur 'is' sert à tester l'identité de deux objets, et non leur égalité. C'est en fait le strict équivalent de :
if id(v) != id('TEST')
Et ce n'est en aucun cas l'opérateur qui convient pour la comparaison que tu fais ici. Si tu veux tester une égalité de valeur, utilise l'opérateur '=='.
Pour info, voici deux ou trois cas d'utilisation correcte de 'is':
a = 'TEST' b = a print a is b
c = None print c is None:
def toto(): pass
d = toto print d is toto
etc... Comme tu peux le constater, dans aucun de ces cas on ne teste contre un litéral.
(snip)
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement
Manifestement, ta conclusion est (au moins partiellement) erronée. La présence du slash ne modifie en rien le comportement de 'is', bien qu'elle puisse modifier le résultat de ton test.
Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Détail d'implémentation de CPython, qui tente autant que possible de cacher certains objets immutables. Tu aurais pu avoir une surprise similaire avec des entiers:
a = 1 print a is 1 True
b = 1024*1024 print b is 1024*1024 False
ou des expressions booléennes:
print a == 1 True
print (a == 1) is True True
print a == 1 is True False
Bref, et pour résumer : utilise '==' pour une égalité de valeur, et 'is' pour des identités d'objets.
HTH
Bonjour la communauté,
Voici un petit bout de code qui m'intrigue,
v = 'TEST'
if not v is 'TEST':
if v is not 'TEST'
aurais été plus lisible AMHA.
Ceci étant dit, l'opérateur 'is' sert à tester l'identité de deux
objets, et non leur égalité. C'est en fait le strict équivalent de :
if id(v) != id('TEST')
Et ce n'est en aucun cas l'opérateur qui convient pour la comparaison
que tu fais ici. Si tu veux tester une égalité de valeur, utilise
l'opérateur '=='.
Pour info, voici deux ou trois cas d'utilisation correcte de 'is':
a = 'TEST'
b = a
print a is b
c = None
print c is None:
def toto():
pass
d = toto
print d is toto
etc... Comme tu peux le constater, dans aucun de ces cas on ne teste
contre un litéral.
(snip)
J'avoue que je ne comprend pas très bien le fonctionnement de
l'opérateur 'is' dans ces tests.
Manifestement le caractère '/' modifie son comportement
Manifestement, ta conclusion est (au moins partiellement) erronée. La
présence du slash ne modifie en rien le comportement de 'is', bien
qu'elle puisse modifier le résultat de ton test.
Curieusement, je n'avais encore jamais été confronté à cette situation.
Si quelqu'un a une explication, je suis preneur
Détail d'implémentation de CPython, qui tente autant que possible de
cacher certains objets immutables. Tu aurais pu avoir une surprise
similaire avec des entiers:
a = 1
print a is 1
True
b = 1024*1024
print b is 1024*1024
False
ou des expressions booléennes:
print a == 1
True
print (a == 1) is True
True
print a == 1 is True
False
Bref, et pour résumer : utilise '==' pour une égalité de valeur, et 'is'
pour des identités d'objets.
Ceci étant dit, l'opérateur 'is' sert à tester l'identité de deux objets, et non leur égalité. C'est en fait le strict équivalent de :
if id(v) != id('TEST')
Et ce n'est en aucun cas l'opérateur qui convient pour la comparaison que tu fais ici. Si tu veux tester une égalité de valeur, utilise l'opérateur '=='.
Pour info, voici deux ou trois cas d'utilisation correcte de 'is':
a = 'TEST' b = a print a is b
c = None print c is None:
def toto(): pass
d = toto print d is toto
etc... Comme tu peux le constater, dans aucun de ces cas on ne teste contre un litéral.
(snip)
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement
Manifestement, ta conclusion est (au moins partiellement) erronée. La présence du slash ne modifie en rien le comportement de 'is', bien qu'elle puisse modifier le résultat de ton test.
Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Détail d'implémentation de CPython, qui tente autant que possible de cacher certains objets immutables. Tu aurais pu avoir une surprise similaire avec des entiers:
a = 1 print a is 1 True
b = 1024*1024 print b is 1024*1024 False
ou des expressions booléennes:
print a == 1 True
print (a == 1) is True True
print a == 1 is True False
Bref, et pour résumer : utilise '==' pour une égalité de valeur, et 'is' pour des identités d'objets.
HTH
Bruno Desthuilliers
(snip)
is, c'est l'operateur d'égalité d'objet en mémoire.
(repost suite à erreur - Christophe, tu a probablement recu la réponse en privé, si oui mes excuses pour la fausse manip)
'is' est l'opérateur de comparaison d'identité. C'est à dire que :
a is b
est strictement équivalent à:
id(a) == id(b)
(se référer à la définition de id())
Le fait que CPython utilise l'adresse mémoire comme identifiant unique d'un objet, bien qu'évident d'un point de vue pratique, n'est qu'un détail d'implémentation.
Et avant que quelqu'un ne le dise, oui, je sais, je suis puriste et pédant !-)
(snip)
is, c'est l'operateur d'égalité d'objet en mémoire.
(repost suite à erreur - Christophe, tu a probablement recu la réponse
en privé, si oui mes excuses pour la fausse manip)
'is' est l'opérateur de comparaison d'identité. C'est à dire que :
a is b
est strictement équivalent à:
id(a) == id(b)
(se référer à la définition de id())
Le fait que CPython utilise l'adresse mémoire comme identifiant unique
d'un objet, bien qu'évident d'un point de vue pratique, n'est qu'un
détail d'implémentation.
Et avant que quelqu'un ne le dise, oui, je sais, je suis puriste et
pédant !-)
is, c'est l'operateur d'égalité d'objet en mémoire.
(repost suite à erreur - Christophe, tu a probablement recu la réponse en privé, si oui mes excuses pour la fausse manip)
'is' est l'opérateur de comparaison d'identité. C'est à dire que :
a is b
est strictement équivalent à:
id(a) == id(b)
(se référer à la définition de id())
Le fait que CPython utilise l'adresse mémoire comme identifiant unique d'un objet, bien qu'évident d'un point de vue pratique, n'est qu'un détail d'implémentation.
Et avant que quelqu'un ne le dise, oui, je sais, je suis puriste et pédant !-)
curieusement le '/' seul ne pose pas de problème In [10]: v='/'
In [11]: v is '/' Out[11]: True
j'ai pas d'explication...
-- William Dodé - http://flibuste.net Informaticien indépendant
Christophe Cavalaria
Salvatore wrote:
Bonjour la communauté,
Voici un petit bout de code qui m'intrigue,
v = 'TEST' if not v is 'TEST': ... print "v est different de 'TEST'"
... else: ... print "v est egal a 'TEST'" ... v est egal a 'TEST'
v = 'N/A' if not v is 'N/A': ... print "v est different de 'N/A'"
... else: ... print "v est egal a 'N/A'" ... v est different de 'N/A'
v != 'N/A' False
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Cordialement
Salvatore
is, c'est l'operateur d'égalité d'objet en mémoire. Il est tout à fait envisageable d'avoir en deux string différentes en mémoire ayant le même contenu. A ce moment, les strings comparent à faux avec is mais à vrai avec == car ce dernier test le contenu des objets
a is b <=> id(a) == id(b)
Après, la ligne de commande python ou le compilateur .py=>.pyc peut faire certaines optimisations qui fait que ce genre de code renvoit vrai sur le premier print :
a = "test" b = "test" print a is b a += "e" b += "e" print a is b
Mais en général, vous obtenez toujours faux sur le deuxième même si manifestement a == b.
Salvatore wrote:
Bonjour la communauté,
Voici un petit bout de code qui m'intrigue,
v = 'TEST'
if not v is 'TEST':
... print "v est different de 'TEST'"
... else:
... print "v est egal a 'TEST'"
...
v est egal a 'TEST'
v = 'N/A'
if not v is 'N/A':
... print "v est different de 'N/A'"
... else:
... print "v est egal a 'N/A'"
...
v est different de 'N/A'
v != 'N/A'
False
J'avoue que je ne comprend pas très bien le fonctionnement de
l'opérateur 'is' dans ces tests.
Manifestement le caractère '/' modifie son comportement
Curieusement, je n'avais encore jamais été confronté à cette situation.
Si quelqu'un a une explication, je suis preneur
Cordialement
Salvatore
is, c'est l'operateur d'égalité d'objet en mémoire. Il est tout à fait
envisageable d'avoir en deux string différentes en mémoire ayant le même
contenu. A ce moment, les strings comparent à faux avec is mais à vrai avec
== car ce dernier test le contenu des objets
a is b <=> id(a) == id(b)
Après, la ligne de commande python ou le compilateur .py=>.pyc peut faire
certaines optimisations qui fait que ce genre de code renvoit vrai sur le
premier print :
a = "test"
b = "test"
print a is b
a += "e"
b += "e"
print a is b
Mais en général, vous obtenez toujours faux sur le deuxième même si
manifestement a == b.
v = 'TEST' if not v is 'TEST': ... print "v est different de 'TEST'"
... else: ... print "v est egal a 'TEST'" ... v est egal a 'TEST'
v = 'N/A' if not v is 'N/A': ... print "v est different de 'N/A'"
... else: ... print "v est egal a 'N/A'" ... v est different de 'N/A'
v != 'N/A' False
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Cordialement
Salvatore
is, c'est l'operateur d'égalité d'objet en mémoire. Il est tout à fait envisageable d'avoir en deux string différentes en mémoire ayant le même contenu. A ce moment, les strings comparent à faux avec is mais à vrai avec == car ce dernier test le contenu des objets
a is b <=> id(a) == id(b)
Après, la ligne de commande python ou le compilateur .py=>.pyc peut faire certaines optimisations qui fait que ce genre de code renvoit vrai sur le premier print :
a = "test" b = "test" print a is b a += "e" b += "e" print a is b
Mais en général, vous obtenez toujours faux sur le deuxième même si manifestement a == b.
Salvatore
Salvatore wrote:
Mais en général, vous obtenez toujours faux sur le deuxième même si manifestement a == b.
Merci pour cette explication, Christophe. Il faut en conclure que pour tester le 'contenu' d'une variable il faut sytématiquement utiliser l'opérateur '==' et non l'opérateur 'is', qui lui est réservé pour tester l'identité de 2 objets.
Salvatore wrote:
Mais en général, vous obtenez toujours faux sur le deuxième même si
manifestement a == b.
Merci pour cette explication, Christophe.
Il faut en conclure que pour tester le 'contenu' d'une variable
il faut sytématiquement utiliser l'opérateur '==' et non l'opérateur
'is', qui lui est réservé pour tester l'identité de 2 objets.
Mais en général, vous obtenez toujours faux sur le deuxième même si manifestement a == b.
Merci pour cette explication, Christophe. Il faut en conclure que pour tester le 'contenu' d'une variable il faut sytématiquement utiliser l'opérateur '==' et non l'opérateur 'is', qui lui est réservé pour tester l'identité de 2 objets.
Salvatore
curieusement le '/' seul ne pose pas de problème In [10]: v='/'
In [11]: v is '/' Out[11]: True
a = '/' a is '/' False
Décidément notre ami Python nous joue des tours :-)
curieusement le '/' seul ne pose pas de problème
In [10]: v='/'
In [11]: v is '/'
Out[11]: True
a = '/'
a is '/'
False
Décidément notre ami Python nous joue des tours :-)
Et avant que quelqu'un ne le dise, oui, je sais, je suis puriste et pédant !-)
Aucune importance ! ...sans préjuger du fait éventuel que ce soit vrai ;-)
Encolpe Degoute
Bonjour la communauté,
Voici un petit bout de code qui m'intrigue,
v = 'TEST' if not v is 'TEST': .... print "v est different de 'TEST'"
.... else: .... print "v est egal a 'TEST'" .... v est egal a 'TEST'
v = 'N/A' if not v is 'N/A': .... print "v est different de 'N/A'"
.... else: .... print "v est egal a 'N/A'" .... v est different de 'N/A'
v != 'N/A' False
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Pour faire un équivalence au C, 'is' vérifie une référence. Mais python est avare en mémoire: s'il peu utiliser le même objet deux fois il le fait:
_MARKER = 'XXX'
a = 'XXX' a is _MARKER True
a = a[:] # force la copie a is _MARKER True
a = a + 'X' a is _MARKER False
b = _MARKER b is _MARKER True
b = b + 'X' b is _MARKER False
Lorsque deux chaines de caractères sont identiques python utilise la même référence en mémoire s'il considère que cela est pertinent, mais pas toujours. Dans le cas des tests a et b il a fallu modifier la valeur des variables pour changer de références. Conclusion: utiliser 'is' sur des chaines de caractère est une source de bug. Il vaut mieux utiliser '==' qui est plus adapté.
Maintenant, le cas des listes (mais pas des tuples):
_MARKER2 = ['1', '2'] c = _MARKER2
c is _MARKER2 True
c.append(3) c is _MARKER2 True
c == _MARKER2 True
_MARKER2 ['1', '2', 3]
La variable c, via l'affection initiale, partage la même référence que le marqueur. Modifier la variable revient à modifier le marqueur.
Aller, la victoire sur les néo-zélandais mérite un petit mal de crane:
from copy import copy d = copy(_MARKER2)
d is _MARKER2 False
d == _MARKER2 True
Que se passe-t-il ? 'is' vérifie les pointeurs et l'utilisation de 'copy' nous assure qu'ils sont différents. '==' vérifie les valeurs et l'utilisation de 'copy', ou de deepcopy dans les cas les plus complexes, nous assure qu'elles sont identiques.
d.append(4)
d is _MARKER2 False
d == _MARKER2 False
La variable d est bien indépendante du marqueur.
Conclusion générale: La question de l'utilisation de 'is' est un grand classique de python et pour faire simple il ne faut pas l'utiliser sauf lorsque l'on veut s'assurer que deux objets utilisent la même référence. Le cas le plus fréquent de l'utilisation de 'is' est la vérification d'une valeur passée en argument d'un fonction ou d'un méthode.
Amicalement, -- Encolpe DEGOUTE http://encolpe.degoute.free.fr/ Logiciels libres, hockey sur glace et autres activités cérébrales
Bonjour la communauté,
Voici un petit bout de code qui m'intrigue,
v = 'TEST'
if not v is 'TEST':
.... print "v est different de 'TEST'"
.... else:
.... print "v est egal a 'TEST'"
....
v est egal a 'TEST'
v = 'N/A'
if not v is 'N/A':
.... print "v est different de 'N/A'"
.... else:
.... print "v est egal a 'N/A'"
....
v est different de 'N/A'
v != 'N/A'
False
J'avoue que je ne comprend pas très bien le fonctionnement de
l'opérateur 'is' dans ces tests.
Manifestement le caractère '/' modifie son comportement
Curieusement, je n'avais encore jamais été confronté à cette situation.
Si quelqu'un a une explication, je suis preneur
Pour faire un équivalence au C, 'is' vérifie une référence.
Mais python est avare en mémoire: s'il peu utiliser le même objet deux
fois il le fait:
_MARKER = 'XXX'
a = 'XXX'
a is _MARKER
True
a = a[:] # force la copie
a is _MARKER
True
a = a + 'X'
a is _MARKER
False
b = _MARKER
b is _MARKER
True
b = b + 'X'
b is _MARKER
False
Lorsque deux chaines de caractères sont identiques python utilise la
même référence en mémoire s'il considère que cela est pertinent, mais
pas toujours. Dans le cas des tests a et b il a fallu modifier la valeur
des variables pour changer de références.
Conclusion: utiliser 'is' sur des chaines de caractère est une source de
bug. Il vaut mieux utiliser '==' qui est plus adapté.
Maintenant, le cas des listes (mais pas des tuples):
_MARKER2 = ['1', '2']
c = _MARKER2
c is _MARKER2
True
c.append(3)
c is _MARKER2
True
c == _MARKER2
True
_MARKER2
['1', '2', 3]
La variable c, via l'affection initiale, partage la même référence que
le marqueur. Modifier la variable revient à modifier le marqueur.
Aller, la victoire sur les néo-zélandais mérite un petit mal de crane:
from copy import copy
d = copy(_MARKER2)
d is _MARKER2
False
d == _MARKER2
True
Que se passe-t-il ?
'is' vérifie les pointeurs et l'utilisation de 'copy' nous assure qu'ils
sont différents.
'==' vérifie les valeurs et l'utilisation de 'copy', ou de deepcopy dans
les cas les plus complexes, nous assure qu'elles sont identiques.
d.append(4)
d is _MARKER2
False
d == _MARKER2
False
La variable d est bien indépendante du marqueur.
Conclusion générale:
La question de l'utilisation de 'is' est un grand classique de python et
pour faire simple il ne faut pas l'utiliser sauf lorsque l'on veut
s'assurer que deux objets utilisent la même référence.
Le cas le plus fréquent de l'utilisation de 'is' est la vérification
d'une valeur passée en argument d'un fonction ou d'un méthode.
Amicalement,
--
Encolpe DEGOUTE
http://encolpe.degoute.free.fr/
Logiciels libres, hockey sur glace et autres activités cérébrales
v = 'TEST' if not v is 'TEST': .... print "v est different de 'TEST'"
.... else: .... print "v est egal a 'TEST'" .... v est egal a 'TEST'
v = 'N/A' if not v is 'N/A': .... print "v est different de 'N/A'"
.... else: .... print "v est egal a 'N/A'" .... v est different de 'N/A'
v != 'N/A' False
J'avoue que je ne comprend pas très bien le fonctionnement de l'opérateur 'is' dans ces tests. Manifestement le caractère '/' modifie son comportement Curieusement, je n'avais encore jamais été confronté à cette situation. Si quelqu'un a une explication, je suis preneur
Pour faire un équivalence au C, 'is' vérifie une référence. Mais python est avare en mémoire: s'il peu utiliser le même objet deux fois il le fait:
_MARKER = 'XXX'
a = 'XXX' a is _MARKER True
a = a[:] # force la copie a is _MARKER True
a = a + 'X' a is _MARKER False
b = _MARKER b is _MARKER True
b = b + 'X' b is _MARKER False
Lorsque deux chaines de caractères sont identiques python utilise la même référence en mémoire s'il considère que cela est pertinent, mais pas toujours. Dans le cas des tests a et b il a fallu modifier la valeur des variables pour changer de références. Conclusion: utiliser 'is' sur des chaines de caractère est une source de bug. Il vaut mieux utiliser '==' qui est plus adapté.
Maintenant, le cas des listes (mais pas des tuples):
_MARKER2 = ['1', '2'] c = _MARKER2
c is _MARKER2 True
c.append(3) c is _MARKER2 True
c == _MARKER2 True
_MARKER2 ['1', '2', 3]
La variable c, via l'affection initiale, partage la même référence que le marqueur. Modifier la variable revient à modifier le marqueur.
Aller, la victoire sur les néo-zélandais mérite un petit mal de crane:
from copy import copy d = copy(_MARKER2)
d is _MARKER2 False
d == _MARKER2 True
Que se passe-t-il ? 'is' vérifie les pointeurs et l'utilisation de 'copy' nous assure qu'ils sont différents. '==' vérifie les valeurs et l'utilisation de 'copy', ou de deepcopy dans les cas les plus complexes, nous assure qu'elles sont identiques.
d.append(4)
d is _MARKER2 False
d == _MARKER2 False
La variable d est bien indépendante du marqueur.
Conclusion générale: La question de l'utilisation de 'is' est un grand classique de python et pour faire simple il ne faut pas l'utiliser sauf lorsque l'on veut s'assurer que deux objets utilisent la même référence. Le cas le plus fréquent de l'utilisation de 'is' est la vérification d'une valeur passée en argument d'un fonction ou d'un méthode.
Amicalement, -- Encolpe DEGOUTE http://encolpe.degoute.free.fr/ Logiciels libres, hockey sur glace et autres activités cérébrales