is vergelijkt de identiteit van objecten (d.w.z. wijzen de variabelen naar hetzelfde geheugenlocatie).== (operator eq) vergelijkt de waarden, d.w.z. of de objecten gelijk zijn in termen van hun inhoud.is moet worden gebruikt voor het vergelijken van identiteit (bijvoorbeeld met None of voor singleton-objecten), en niet voor het controleren van gelijkheid van waarden.
Voorbeeld:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
Bij het werken met kleine gehele getallen of strings kan de interpreter gebruik maken van "internering" (cached objects), wat soms is waar maakt voor gelijkwaardige waarden, maar dit mag niet worden gebruikt in de logica van het programma.
Vraag: Wat zal de volgende code afdrukken?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)Waarom?
Antwoord:
Voor waarden van -5 tot 256 gebruikt Python een pool van gehele getallen. Waarden in dit bereik wijzen altijd naar dezelfde objecten, dus a is b zal True geven. 257 ligt buiten de pool, dus c is d zal False zijn (de objecten zijn onafhankelijk).
Geschiedenis
In een microservice werd de gelijkheid van strings gecontroleerd met is in plaats van ==. Vanwege optimalisaties van de interpreter werkte het programma "stabiel" in tests, maar begon te falen na recompilatie of andere wijzigingen in de omgeving.
Een ontwikkelaar gebruikte de operator is in plaats van == voor het vergelijken van getallen. Dit werkte voor kleine getallen (dankzij de pool), maar voor grotere getallen leidde het tot fouten en onvoorspelbare resultaten, wat leidde tot onjuiste berekeningen.
Bij het ontwerpen van een autorisatiesysteem controleerden ze de ontvangen JSON met is None (correct), en maakten daarna op dezelfde manier gebruik van strings: if status is "ok". Dit bleek een fout te zijn — soms voldeed de voorwaarde niet, wat leidde tot onjuiste dataverwerking.