Why Python's `is` Keyword Will Betray You If You Trust It for Equality

작성자

카테고리:

← 피드로
DEV Community · Ameer Abdullah · 2026-07-19 개발(SW)
Cover image for Why Python's `is` Keyword Will Betray You If You Trust It for Equality

Ameer Abdullah

This is one of the most commonly misused Python features and it fails silently, which makes it especially dangerous in production code.

a = "hello"
b = "hello"
print(a == b)
print(a is b)

Enter fullscreen mode Exit fullscreen mode

Both print True. Safe, right?

Now try this:

a = "hello world"
b = "hello world"
print(a == b)
print(a is b)

Enter fullscreen mode Exit fullscreen mode

a == b prints True. a is b might print False.

Same code structure. Different result. Here is exactly why.

What is and == Actually Check

== checks value equality. Do these two objects represent the same value?

is checks identity equality. Are these two names pointing to the exact same object in memory?

Two objects can be equal in value while being completely different objects in memory.

String Interning

Python automatically interns some strings. Interning means Python reuses a single object for multiple names with the same value, rather than creating separate objects.

Short strings that look like valid Python identifiers are automatically interned. Longer strings or strings with spaces are not always interned.

a = "hello"
b = "hello"
print(a is b)  # True -- both point to the same interned object

a = "hello world"
b = "hello world"
print(a is b)  # False -- two separate objects (implementation dependent)

Enter fullscreen mode Exit fullscreen mode

The behavior for longer strings is implementation dependent and version dependent. You cannot rely on it.

Integer Caching

Python caches integers from -5 to 256. Integers in this range are always the same object regardless of how many names point to them.

a = 100
b = 100
print(a is b)  # True -- cached integer, same object

a = 1000
b = 1000
print(a is b)  # False -- outside cache range, separate objects

Enter fullscreen mode Exit fullscreen mode

a = 256
b = 256
print(a is b)  # True -- last cached integer

a = 257
b = 257
print(a is b)  # False -- first uncached integer

Enter fullscreen mode Exit fullscreen mode

The Interview Trap

x = None
y = None
print(x is y)   # True -- None is a singleton
print(x == y)   # True

x = []
y = []
print(x is y)   # False -- two separate empty list objects
print(x == y)   # True -- both represent empty lists

Enter fullscreen mode Exit fullscreen mode

The canonical use case for is is checking against None, True, and False. These are singletons in Python. Every None in your program is the same object.

# Correct pattern
if value is None:
    handle_missing()

# Incorrect pattern (works by accident, not by design)
if value == None:
    handle_missing()

Enter fullscreen mode Exit fullscreen mode

The == version works because NoneType.__eq__ is implemented but using is is the semantically correct choice and is what PEP 8 requires.

The Practical Rule

Use == for value comparison in all application code.
Use is only for checking against None, True, and False.
Never use is to compare strings or integers in application code, even if it works in testing.

Practice identity vs equality problems at PyCodeIt.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다