comparer deux chaînes avec 'is' & # 8212; ne fonctionne pas comme prévu
-
06-07-2019 - |
Question
J'essaie de comparer deux chaînes avec est . Une chaîne est renvoyée par une fonction et l'autre est simplement déclarée dans la comparaison. est un test d'identité d'identité d'objet, mais selon cette page , cela fonctionne également avec deux chaînes identiques en raison de l'optimisation de la mémoire de Python. Mais ce qui suit ne fonctionne pas:
def uSplit(ustring):
#return user minus host
return ustring.split('!',1)[0]
user = uSplit('theuser!host')
print type(user)
print user
if user is 'theuser':
print 'ok'
else:
print 'failed'
user = 'theuser'
if user is 'theuser':
print 'ok'
La sortie:
type 'str' theuser failed ok
Je suppose que la raison en est qu’une chaîne renvoyée par une fonction est un "type" différent. de chaîne qu'un littéral de chaîne. Est-il possible d'obtenir une fonction pour renvoyer un littéral de chaîne? Je sais que je pourrais utiliser == , mais je suis simplement curieux.
La solution
Le site que vous citez dit ceci:
Si deux littéraux de chaîne sont égaux, ils ont été placés dans le même emplacement mémoire.
Mais
uSplit('theuser!host')
n'est pas un littéral de chaîne - c'est le résultat d'une opération sur le littéral 'utilisateur_hôte! hôte
.
Quoi qu'il en soit, vous ne devriez généralement pas vérifier l'égalité des chaînes à l'aide de is
, car cette optimisation de la mémoire n'est en tout cas qu'un détail d'implémentation sur lequel vous ne devriez pas compter.
De même, vous devez utiliser est
pour des éléments tels que est Aucun
. Utilisez-le pour vérifier si deux objets - des classes que vous avez conçues - sont la même instance. Vous ne pouvez pas facilement l'utiliser pour des chaînes ou des nombres car les règles de création de ces classes intégrées sont complexes. Certaines chaînes sont internées. De même, certains numéros sont internés.
Autres conseils
La page que vous avez citée indique "Si deux chaînes littéraux sont égaux, ils ont été placés dans le même emplacement mémoire". (c'est moi qui souligne). Python intègre des chaînes littérales, mais les chaînes renvoyées par une fonction quelconque sont des objets distincts. L'opérateur est
peut être considéré comme une comparaison de pointeur. Deux objets différents ne seront donc pas identiques (même s'ils contiennent les mêmes caractères, c'est-à-dire qu'ils sont égaux).
Ce que vous avez rencontré est le fait que Python n’interne pas toujours toutes ses chaînes. Plus de détails ici:
http://mail.python.org/pipermail/tutor /2009-juillet/070157.html