Reputation: 288
So the is
keyword returns true only if the two arguments point to the same object. My question is related to the snippet below.
This snippet
number = None
if number is None:
print("PEP 8 Style Guide prefers this pattern")
Outputs
>>PEP 8 Style Guide prefers this pattern
Does this mean when I assign number = None
then it is only by reference, because is
checks if it is the same object. I'm so confused why this happens?? Am I wrong?? Why was this design choice made?
Upvotes: 1
Views: 106
Reputation: 2426
This is because of two reasons.
In the following code
x = object()
y = x
print(x is y) # True
print(id(x)) # 139957673835552
print(id(y)) # 139957673835552
Calling object()
creates a new structure in memory, whose unique identifier can be accessed with the id()
function.
You can imagine x
and y
being arrows pointing to the same object, and this is why their underlying identifier is the same in both cases.
As such, when assigning None
to a variable, you're just saying "number
is an alias, an arrow pointing to the object returned by writing None
". You can check that
number = None
print(id(None), id(number))
will give you the same identifier two times. But wait! What if you do it for a big number like 100000
?
number = 100000
print(id(100000), id(number)) # Different values!
This means that the same literal, written two times, can return different objects, bringing up the next reason.
Note that no matter how many times you get the None
identifier, you get the same one.
print(id(None)) # 139957682420224
print(id(None)) # 139957682420224
print(id(None)) # 139957682420224
This is because writing None
doesn't create a new object, as in the first example, because the language specification guarantees that there's only one possible object of NoneType
in memory. In other words, there's only one possible object returned by writing None
, making comparisons with is
work as expected. This is a good design choice: There's only one canonical way for saying that a variable (an arrow) points to nothingness.
In fact, using is
is encouraged as the Pythonic way of checking that a variable is None
.
You can also get the class of the object by writing
NoneType = type(None)
and notice how
NoneType() is None
is true.
Note: The uniqueness property is also satisfied by other literals, particularly small numbers, for performance reasons.
Upvotes: 3
Reputation: 532268
All assignments are by reference (see Facts and myths about Python names and values). However, the language guarantees that None
is the only object of its type. That value is created at startup, and the literal None
will always produce a reference to that value.
>>> a = None; b = None
>>> a is b
True
>>> a = None
>>> b = None
>>> a is b
True
Compare to a literal like 12345
, which may or may not produce a reference to an existing value of type int
.
>>> a = 12345; b = 12345
>>> a is b
True
>>> a = 12345
>>> b = 12345
>>> a is b
False
Why this produces different results isn't really important, other than to say that an implementation can create new objects from int
literals if it prefers.
Upvotes: 2