[Python-Dev] Re: Re: Re: print "%X" % id(object()) not so nice

Tim Peters tim.peters at gmail.com
Sat Nov 20 17:21:28 CET 2004


[Terry Reedy]
>> I, on the other hand, having never used either, find the difference in
>> printed ids in
>>
>> >>> def f(): pass
>> >>> f, id(f)
>> (<function f at 0x00868158>, 8814936)
>>
>> at least mildly disturbing.  Do you only need to do such matching for
>> complex objects that get the <type name at 0x########>
>> representation?

[Michael Hudson]
> This hardly seems worth discussing :)

Then it's a topic for me <wink>!

> It's a pointer.  Pointers are printed in hex.  It's Just The Way It
> Is.  I don't know why.
>
> Actually, the "0x00868158" above is produced by C's %p format
> operator.  So, in fact, ANSI C is probably why it is The Way It Is.

repr starts with %p, but %p is ill-defined, so Python goes on to
ensure the result starts with "0x".  C doesn't even say that %p
produces hex digits, but all C systems we know of do(*), so Python
doesn't try to force that part.

As to "why hex?", it's for low-level debugging.  For example, stack,
register and memory dumps for binary machines almost always come in
some power-of-2 base, usually hex, and searching for a stored address
is much easier if it's shown in the same base.

OTOH, id(Q) promises to return an integer that won't be the same as
the id() of any other object over Q's lifetime.  CPython returns Q's
memory address, but CPython never moves objects in memory, so CPython
can get away with returning the address.  Jython does something very
different for id(), because it must -- the Java VM may move an object
in memory.

Python doesn't promise to return a postive integer for id(), although
it may have been nicer if it did.  It's dangerous to change that now,
because some code does depend on the "32 bit-ness as a signed integer"
accident of CPython's id() implementation on 32-bit machines.  For
example, code using struct.pack(), or code using one of ZODB's
specialized int-key BTree types with id's as keys.

Speaking of which, current ZODB has a positive_id() function, used to
format id()'s in strings where a sign bit would get in the way.

(*) The %p in some C's for early x86 systems, using "segment + offset"
mode, stuck a colon "in the middle" of the pointer output, to visually
separate the segment from the offset.  The two parts were still shown
in hex, though.


More information about the Python-Dev mailing list