Pourquoi l'opérateur \'is\' se comporte-t-il différemment avec des entiers non mis en cache à l'intérieur et à l'extérieur d'une fonction en Python ?

Mary-Kate Olsen
Libérer: 2024-10-31 19:22:02
original
256 Les gens l'ont consulté

Why does the 'is' operator behave differently with non-cached integers inside and outside a function in Python?

Comportement inattendu de l'opérateur 'is' avec des entiers non mis en cache

Enquête

Lors de l'expérimentation avec l'interpréteur de Python, un paradoxe a été remarqué concernant le ' est l'opérateur. Plus précisément, « is » renvoie True lorsqu'il est évalué dans une fonction mais False lorsqu'il est évalué en dehors de celle-ci :

>>> def func():
...     a = 1000
...     b = 1000
...     return a is b
...

>>> a = 1000
>>> b = 1000
>>> a is b, func()
(False, True)
Copier après la connexion

Puisque « is » évalue l'« id » de l'objet, cela implique que dans la fonction « func », 'a' et 'b' font référence à la même instance int. Cependant, en dehors de la fonction, ils font référence à des objets différents. Pourquoi est-ce le cas ?

Explication

Le manuel de référence Python offre une clarification perspicace :

"Un bloc est un morceau de texte de programme Python qui est exécuté comme une unité . Chaque commande saisie de manière interactive est un bloc."

Au sein d'une fonction, il existe un seul bloc de code, contenant un seul objet pour le nombre 1000. Ainsi, 'id(a)' et 'id(b)'. renvoie la même valeur, ce qui donne une évaluation True.

En dehors de la fonction, nous avons deux objets de code distincts, chacun avec son objet pour 1000. Par conséquent, 'id(a)' et 'id(b) 'sont différents, conduisant à une évaluation fausse.

Cette bizarrerie n'est pas exclusive aux nombres entiers. Des résultats similaires sont observés avec, par exemple, les littéraux float. N'oubliez pas que comparer des objets pour déterminer leur identité (en utilisant « est ») est généralement déconseillé ; à la place, l'opérateur d'égalité ('==') doit être utilisé.

Démonstration de code

Pour mieux comprendre, nous pouvons approfondir les objets de code pour les deux cas :

Dans la fonction 'func' :

>>> print(dis.code_info(func))
...
Constants:
   0: None
   1: 1000
Copier après la connexion

Nous avons une seule instance 'int' pour 1000 qui est attribuée à la fois à 'a' et 'b'.

En dehors de la fonction 'func' :

>>> com1 = compile("a=1000", filename="", mode="single")
>>> com2 = compile("b=1000", filename="", mode="single")
>>> id(com1.co_consts[0]) == id(com2.co_consts[0])
False
Copier après la connexion

Nous voyons que chaque objet de code a son instance de 1000, conduisant à l'évaluation False.

Notes

  • Cette observation concerne CPython, l'implémentation Python la plus largement utilisée.
  • Les instructions chaînées sont évaluées à True pour « est » car elles sont traitées comme un seul bloc de code.
  • L'exécution au niveau du module donne également True.
  • Les contrôles d'identité utilisant « est » ne sont pas recommandés pour les objets mutables, car ils seront toujours évalués à False.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!