is operator versus id() function

  • Thread starter Candide Dandide
  • Start date
C

Candide Dandide

Until now, I was quite sure that the is operator acts the same as the id builtin function, or, to be more formal, that o1 is o2 to be exactly equivalent to id(o1) == id(o2). This equivalence is reported in many books, forinstance Martelli's Python in a Nutshell.

But with the following code, I'm not still sure the equivalence above is correct. Here's the code :


#--------------------------------------------------------
class A(object):
def f(self):
print "A"

a=A()
print id(A.f) == id(a.f), A.f is a.f
#--------------------------------------------------------


outputing:

True False

So, could someone please explain what exactly the is operator returns ? Theofficial doc says :

The ?is? operator compares the identity of two objects; the id() function returns an integer representing its identity (currently implemented as its address).
 
A

Arnaud Delobelle

Until now, I was quite sure that the is operator acts the same as the id builtin function, or, to be more formal, that o1 is o2 to be exactly equivalent to id(o1) == id(o2). This equivalence is reported in many books, for instance Martelli's Python in a Nutshell.

But with the following code, I'm not still sure the equivalence above is correct. Here's the code :


#--------------------------------------------------------
class A(object):
def f(self):
print "A"

a=A()
print id(A.f) == id(a.f), A.f is a.f
#--------------------------------------------------------


outputing:

True False

So, could someone please explain what exactly the is operator returns ? The official doc says :

The ‘is‘ operator compares the identity of two objects; the id() function returns an integer representing its identity (currently implemented as its address).

And the doc is right!
False False

You've fallen victim to the fact that CPython is very quick to collect
garbage. More precisely, when Python interprets `id(A.f) == id(a.f)`,
it does the following:

1. Create a new unbound method (A.f)
2. Calculate its id
3. Now the refcount of A.f is down to 0, so it's garbage collected
4 Create a new bound method (a.f) **and very probably use the same
memory slot as that of A.f**
5 Calculate its id
6 ...
 
C

candide

Le vendredi 5 avril 2013 16:53:55 UTC+2, Arnaud Delobelle a ?crit?:

You've fallen victim to the fact that CPython is very quick to collect

garbage.


OK, I get it but it's a fairly unexpected behavior.
Thanks for the demonstrative snippet of code and the instructive answer.
 
C

candide

Le vendredi 5 avril 2013 16:53:55 UTC+2, Arnaud Delobelle a ?crit?:

You've fallen victim to the fact that CPython is very quick to collect

garbage.


OK, I get it but it's a fairly unexpected behavior.
Thanks for the demonstrative snippet of code and the instructive answer.
 
T

Tim Delaney

Le vendredi 5 avril 2013 16:53:55 UTC+2, Arnaud Delobelle a écrit :




OK, I get it but it's a fairly unexpected behavior.
Thanks for the demonstrative snippet of code and the instructive answer.

If you read the docs for id() <
http://docs.python.org/3.3/library/functions.html#id>, you will see that it
says:

Return the "identity" of an object. This is an integer which is guaranteed
to be unique and constant for this object during its lifetime. Two objects
with non-overlapping lifetimes may have the same id() value.

If you think it could explain things better, please submit a doc bug.

I think part of your confusion here is that bound methods in Python are
created when accessed. So A.f and a.f are not the same object - one is a
function (an unbound method, but there's no distinction in Python 3.x) and
the other is a bound method. For that reason, accessing a.f twice will
return two different bound method instances.

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information..... def f(self):
.... print("A")
....
Tim Delaney
 
N

Nobody

So, could someone please explain what exactly the is operator returns ?
The official doc says :

The ‘is‘ operator compares the identity of two objects; the id()
function returns an integer representing its identity (currently
implemented as its address).

The docs are correct.

But an identity is only unique for the lifetime of the object, so
"x is y" and "id(x)==id(y)" are only equivalent if the lifetimes of
x and y overlap.

If the objects have disjoint lifetimes (i.e. one is created after the
other has been destroyed), then it's possible for id() to return the same
value for both objects, so id(x)==id(y) can return a "false positive"
result, as happened in your example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top