is implemented with id ?

F

Franck Ditter

Hi !
a is b <==> id(a) == id(b) in builtin classes.
Is that true ?
Thanks,

franck
 
B

Benjamin Kaplan

Hi !
a is b <==> id(a) == id(b) in builtin classes.
Is that true ?
Thanks,

franck

No. It is true that if a is b then id(a) == id(b) but the reverse is
not necessarily true. id is only guaranteed to be unique among objects
alive at the same time. If objects are discarded, their ids may be
reused even though the objects are not the same.
 
S

Steven D'Aprano

Hi !
a is b <==> id(a) == id(b) in builtin classes. Is that true ?

Not just for builtin classes, for any objects, provided that they are
alive at the same time.

There is no guarantee whether IDs will be re-used. Some versions of
Python do re-use IDs, e.g. CPython:

steve@runes:~$ python
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a) 3074285228L
del a
b = [100, 200]
id(b)
3074285228L

but others do not, e.g. Jython and IronPython:

steve@runes:~$ jython
Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)
[OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18
Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a) 1
del a
b = [100, 200]
id(b)
2


steve@runes:~$ ipy
IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a) 43
del a
b = [100, 200]
id(b)
44


CPython especially has the most complicated behaviour with IDs and object
identity:
True


In general, you almost never need to care about IDs and object identity.
The main exception is testing for None, which should always be written as:

if x is None
 
R

Ramchandra Apte

Not just for builtin classes, for any objects, provided that they are

Seeing this thread, I think the is statment should be removed.
It has a replacement syntax of id(x) == id(y) and "a==True" should be automatically changed into memory comparison.
alive at the same time.



There is no guarantee whether IDs will be re-used. Some versions of

Python do re-use IDs, e.g. CPython:



steve@runes:~$ python

Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)

[GCC 4.4.5] on linux2

Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a)
3074285228L
del a
b = [100, 200]
id(b)

3074285228L



but others do not, e.g. Jython and IronPython:



steve@runes:~$ jython

Jython 2.5.1+ (Release_2_5_1, Aug 4 2010, 07:18:19)

[OpenJDK Client VM (Sun Microsystems Inc.)] on java1.6.0_18

Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a)
1
del a
b = [100, 200]
id(b)

2





steve@runes:~$ ipy

IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433

Type "help", "copyright", "credits" or "license" for more information.
a = ["some", "object"]
id(a)
43
del a
b = [100, 200]
id(b)

44





CPython especially has the most complicated behaviour with IDs and object

identity:



True





In general, you almost never need to care about IDs and object identity.

The main exception is testing for None, which should always be written as:



if x is None
 
F

Franck Ditter

Thanks to all, but :
- I should have said that I work with Python 3. Does that matter ?
- May I reformulate the queston : "a is b" and "id(a) == id(b)"
both mean : "a et b share the same physical address". Is that True ?
Thanks,

franck
 
D

Dave Angel

Seeing this thread, I think the is statment should be removed.
It has a replacement syntax of id(x) == id(y) and "a==True" should be automatically changed into memory comparison.

You didn't read the whole message carefully enough. Id's can be reused,
so there are many ways to mess up comparing id's. One is if the two
items x and y are expressions (eg. function calls). You call a
function, and say it returns a new object, you call id() on that object,
and then the object gets discarded. You now have a stale id, and you
haven't even evaluated the second expression yet.

It's id() which is superfluous. But it's useful for debugging, and for
understanding.
 
H

Hans Mulder

Thanks to all, but :
- I should have said that I work with Python 3. Does that matter ?
- May I reformulate the queston : "a is b" and "id(a) == id(b)"
both mean : "a et b share the same physical address". Is that True ?

Yes.

Keep in mind, though, that in some implementation (e.g.
Jython), the physical address may change during the life
time of an object.

It's usually phrased as "a and b are the same object".
If the object is mutable, then changing a will also change b.
If a and b aren't mutable, then it doesn't really matter
whether they share a physical address.

Keep in mind that physical addresses can be reused when an
object is destroyed. For example, in my Python3,


id(math.sqrt(17)) == id(math.cos(17))

returns True, even though the floats involved are different,
because the flaots have non-overlapping lifetimes and the
physical address happens to be reused.


Hope this helps,

-- HansM
 
D

Dave Angel

Please don't top-post. Now your message is out of order, and if I have
to delete the part Benjamin said.

Thanks to all, but :
- I should have said that I work with Python 3. Does that matter ?
- May I reformulate the queston : "a is b" and "id(a) == id(b)"
both mean : "a et b share the same physical address". Is that True ?
Thanks,

No, id() has nothing to do with physical address. The Python language
does not specify anything about physical addresses. Some
implementations may happen to use physical addresses, others arbitrary
integers. And they may reuse such integers, or not. Up to the
implementation.

And as others have pointed out, when you compare two id's, you're
risking that one of them may no longer be valid. For example, the
following expression:

flag = id(func1()) == id(func2())

could very well evaluate to True, even if func1() always returns a
string, and func2() always returns an int. On the other hand, the 'is'
expression makes sure the two expressions are bound to the same object.

If a and b are simple names, and not placeholders for arbitrary
expressions, then I THINK the following would be true:

"a is b" and "id(a) == id(b)" both mean that the names a and b are
bound to the same object at the time the statement is executed.
 
S

Steven D'Aprano

Seeing this thread, I think the is statment should be removed. It has a
replacement syntax of id(x) == id(y)

A terrible idea.

Because "is" is a keyword, it is implemented as a fast object comparison
directly in C (for CPython) or Java (for Jython). In the C implementation
"x is y" is *extremely* fast because it is just a pointer comparison
performed directly by the interpreter.

Because id() is a function, it is much slower. And because it is not a
keyword, Python needs to do a name look-up for it, then push the argument
on the stack, call the function (which may not even be the built-in id()
any more!) and then pop back to the caller.

And worst, *it doesn't even do what you think it does*. In some Python
implementations, IDs can be reused. That leads to code like this, from
CPython 2.7:

py> id("spam ham"[1:]) == id("foo bar"[1:])
True

You *cannot* replace is with id() except when the objects are guaranteed
to both be alive at the same time, and even then you *shouldn't* replace
is with id() because that is a pessimation (the opposite of an
optimization -- something that makes code run slower, not faster).

and "a==True" should be automatically changed into memory comparison.

Absolutely not. That would be a backward-incompatible change that would
break existing programs:

py> 1.0 == True
True
py> from decimal import Decimal
py> Decimal("1.0000") == True
True
 
S

Steven D'Aprano

No, id() has nothing to do with physical address. The Python language
does not specify anything about physical addresses. Some
implementations may happen to use physical addresses, others arbitrary
integers. And they may reuse such integers, or not. Up to the
implementation.

True. In principle, some day there might be a version of Python that runs
on some exotic quantum computer where the very concept of "physical
address" is meaningless. Or some sort of peptide or DNA computer, where
the calculations are performed via molecular interactions rather than by
flipping bits in fixed memory locations.

But less exotically, Frank isn't entirely wrong. With current day
computers, it is reasonable to say that any object has exactly one
physical location at any time. In Jython, objects can move around; in
CPython, they can't. But at any moment, any object has a specific
location, and no other object can have that same location. Two objects
cannot both be at the same memory address at the same time.

So, for current day computers at least, it is reasonable to say that
"a is b" implies that a and b are the same object at a single location.

The second half of the question is more complex:

"id(a) == id(b)" *only* implies that a and b are the same object at the
same location if they exist at the same time. If they don't exist at the
same time, then you can't conclude anything.
 
D

Dave Angel

True. In principle, some day there might be a version of Python that runs
on some exotic quantum computer where the very concept of "physical
address" is meaningless. Or some sort of peptide or DNA computer, where
the calculations are performed via molecular interactions rather than by
flipping bits in fixed memory locations.

But less exotically, Frank isn't entirely wrong. With current day
computers, it is reasonable to say that any object has exactly one
physical location at any time. In Jython, objects can move around; in
CPython, they can't. But at any moment, any object has a specific
location, and no other object can have that same location. Two objects
cannot both be at the same memory address at the same time.

So, for current day computers at least, it is reasonable to say that
"a is b" implies that a and b are the same object at a single location.

You're arguing against something i didn't say. I only said that id()
doesn't promise to be a memory address. i said nothing about what it
might mean if the "is" operator considers them the same.
The second half of the question is more complex:

"id(a) == id(b)" *only* implies that a and b are the same object at the
same location if they exist at the same time. If they don't exist at the
same time, then you can't conclude anything.
But by claiming that id() really means address, and that those addresses
might move during the lifetime of an object, then the fact that the id()
functions are not called simultaneously implies that one object might
move to where the other one used to be before the "move."

I don't claim to know the jython implementation. But you're claiming
that id() means the address of the object, even in jython. So if a
garbage collection can occur during the evaluation of the expression
id(a) == id(b)

then the comparing of id()'s would be useless in jython. Two distinct
objects could each be moved during evaluation, (very) coincidentally
causing the two to have the same addresses at the two times of
evaluation. Or more likely, a single object could move to a new
location, rendering the comparison false. Thus you have false positive
and false negative possible.

I think it much more likely that jython uses integer values for the id()
function, and not physical addresses. I doubt they'd want a race condition.
 
S

Steven D'Aprano

On 09/05/2012 10:41 AM, Steven D'Aprano wrote: [...]
So, for current day computers at least, it is reasonable to say that "a
is b" implies that a and b are the same object at a single location.

You're arguing against something i didn't say. I only said that id()
doesn't promise to be a memory address. i said nothing about what it
might mean if the "is" operator considers them the same.

I'm not arguing at all. I'm agreeing with you, but going into more detail.

But by claiming that id() really means address,

I didn't actually say that. If you re-read Franck Ditter's previous post,
he doesn't actually say that either.

and that those addresses
might move during the lifetime of an object, then the fact that the id()
functions are not called simultaneously implies that one object might
move to where the other one used to be before the "move."

Well, yes, but I expect that implementations where objects can move will
not use memory addresses as IDs. They will do what Jython and IronPython
do and use arbitrary numbers as IDs.

(Oh how I wish CPython hadn't used memory addresses as IDs.)

I don't claim to know the jython implementation. But you're claiming
that id() means the address of the object, even in jython.

Good god no! I'm saying that, *if* a and b exist at the same time, *and*
if id(a) == id(b), *then* a and b must be the same object and therefore
at the same address. That doesn't mean that the ID is the address!

I think it much more likely that jython uses integer values for the id()
function, and not physical addresses.

That's exactly what it does. It appears to be a simple counter: each time
you ask for an object's ID, it gets allocated the next value starting
from 1, and values are never re-used.
 
H

Hans Mulder

But by claiming that id() really means address, and that those addresses
might move during the lifetime of an object, then the fact that the id()
functions are not called simultaneously implies that one object might
move to where the other one used to be before the "move."

Whoa! Not so fast! The id() of an object is guaranteed to not
change during the object's lifetime. So if an implementation
moves objects around (e.g. Jython), then it cannot use memory
addresses for the id() function.
I think it much more likely that jython uses integer values for
the id() function, and not physical addresses.

The id() function is guaranteed to return some flavour of integer.

In Jython, the return values are 1, 2, 3, 4, etc., except, of course,
if you invoke id() on an object you've id'd before, you get the same
number as before.

In current versions of CPython, you do get the (virtual) memory
address, converted to an int (or a long). But then, CPython does
not move objects.

Maybe the next version of CPython should shift id values two or three
bits to the right, just to make sure people don't misinterpret ids as
memory addresses.


Hope this helps,

-- HansM
 
I

Ian Kelly

You *cannot* replace is with id() except when the objects are guaranteed
to both be alive at the same time, and even then you *shouldn't* replace
is with id() because that is a pessimation (the opposite of an
optimization -- something that makes code run slower, not faster).

Shouldn't that be "pessimization" for symmetry?
 
D

Dave Angel

Whoa! Not so fast! The id() of an object is guaranteed to not
change during the object's lifetime. So if an implementation
moves objects around (e.g. Jython), then it cannot use memory
addresses for the id() function.
Which is equivalent to my point. I had mistakenly thought that Steven
was claiming it was always an address, and disproving that claim by what
amounts to reductio ad absurdem.
The id() function is guaranteed to return some flavour of integer.

In Jython, the return values are 1, 2, 3, 4, etc., except, of course,
if you invoke id() on an object you've id'd before, you get the same
number as before.

In current versions of CPython, you do get the (virtual) memory
address, converted to an int (or a long). But then, CPython does
not move objects.

Maybe the next version of CPython should shift id values two or three
bits to the right, just to make sure people don't misinterpret ids as
memory addresses.

I think i'd prefer if it would put it through one step of a CRC32.
 
T

Terry Reedy

Seeing this thread, I think the is statment should be removed.
It has a replacement syntax of id(x) == id(y)

The thread is wrong then.

If the implementation reuses ids, which CPython does,
<expression-1> is <expression-2>
must be implemented as

internal-tem1 = <expression-1>
internal-tem2 = <expression-2>
id(internal-tem1) == id(internal-tem2)

in order to ensure that the two objects exist simultaneously,
so that the id comparison is valid.
and "a==True" should be automatically changed into memory comparison.

I have no idea what that means.
 
T

Terry Reedy

True. In principle, some day there might be a version of Python that runs
on some exotic quantum computer where the very concept of "physical
address" is meaningless.

You mean like the human brain? When people execute Python code, does 0
have an address?
 
D

Dave Angel

The thread is wrong then.

If the implementation reuses ids, which CPython does,
<expression-1> is <expression-2>
must be implemented as

internal-tem1 = <expression-1>
internal-tem2 = <expression-2>
id(internal-tem1) == id(internal-tem2)

in order to ensure that the two objects exist simultaneously,
so that the id comparison is valid.


I have no idea what that means.

It's probably a response to Steve's comment

"""

In general, you almost never need to care about IDs and object identity.
The main exception is testing for None, which should always be written as:

if x is None
"""

Somehow he substituted True for None. Anyway, if one eliminates "is"
then Steve's comment wouldn't apply.
 
D

Dennis Lee Bieber

You mean like the human brain? When people execute Python code, does 0
have an address?

I suspect some day in the future various CAT and similar scanners
will be able to capture the entire brain (3D) in real-time, at which
point a statistical analysis of many people will be able to assign a 3D
Cartesian coordinate to the main activity associated with the concept of
0 (of course, we'll have to differentiate the concept of the glyph 0
from the concept of the quantity/number zero from the word zero...)
 
S

Steven D'Aprano

I have no idea what that means.

I interpret this as meaning that "a == True" should be special-cased by
the interpreter as "a is True" instead of calling a.__eq__.
 

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

Forum statistics

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

Latest Threads

Top