[Tutor] Looks like a judgment bug.

Steven D'Aprano steve at pearwood.info
Fri Apr 12 05:36:33 CEST 2013


On 12/04/13 12:53, Amit Saha wrote:

> So for example:
>
>>>> a=1
>>>> b=1
>>>> a is b
> True
>>>> id(a) == id(b)
> True


This is not a very good example, because that behaviour itself is implementation-dependent and not guaranteed. For example, in IronPython 2.6 I get completely different behaviour:

>>> a = 1
>>> b = 1
>>> a is b
False
>>> print id(a), id(b)
43 44


Even in CPython, the implementation you are probably using, the behaviour will depend on all sorts of factors, such as the type of the object, and even the value:

py> a = 10001
py> b = 10001
py> a is b
False

py> a = 1.0
py> b = 1.0
py> a is b
False




>So, when are identifiers same and when not? That
> depends on the type of object - mutable or immutable.

No, not really. The best you can say is this:

If Python has a choice between creating a new object, and re-using an existing object, and the object is mutable, Python will never re-use the object since that might introduce bugs. If the object is immutable, Python *may* re-use it, or it may not.


When does Python have a choice between re-using existing objects? That's a complicated question, and there's no straightforward answer. The best I can do is give some examples:


# References to a name will ALWAYS use the same object:
x is x  # always True


# References to another identifier MIGHT re-use the same object:
x.attr is x.attr  # sometimes True, sometimes False
x[index] is x[index]  # the same


# References to a literal MIGHT re-use the same object, if it is immutable:
'x' is 'x'  # might be True
['x'] is ['x']  # always False


# The same literal on the same line of code MIGHT be re-used:
x = 123.5; y = 123.5; x is y  # might be True

# ...even if they aren't re-used when on separate lines.
x = 123.5
y = 123.5
x is y  # probably will be False


# If two or more identifiers are assigned to a value at the same time,
# Python GUARANTEES to use the same object:
x = y = anything_you_like()
x is y  # always True


# Assignment in general never makes a new object:
x = something()
y = x
x is y  # always True[1]


Object identity is almost never important. About the only time it is important is when comparing things to None.

But in practice, you can expect (but not rely on!) CPython to re-use the following:

* Small integers. Which values count as small depend on the version, but -1 to 100 is common.

* Strings that look like identifiers, e.g. "x", "item", but not "hello world" or "?".

But don't rely on this, as it is not guaranteed and could go away at any time.




[1] Technically, if you change the current namespace to a custom dict type, you could do anything you like. But that's cheating, and it's harder than it sounds to change the current namespace.

-- 
Steven


More information about the Tutor mailing list