hex(id(...)) and negative id's, 6 questions

Bengt Richter bokr at oz.net
Thu Feb 12 14:20:47 EST 2004


On Tue, 10 Feb 2004 23:12:50 +0100, Gerrit <gerrit at nl.linux.org> wrote:

>Dietrich Epp wrote:
>> >However, since I upgraded to Fedora Core 1 and Linux Kernel
>> >2.4.22-1.2163.nptl, id(obj) is usually negative. Why is it negative?
>>=20
>> My guess is that it's due to changes in memory allocation.  It's=20
>> nothing to worry about.  Don't depend on the values returned by id(),=20
>> they depend on the OS, the version of Python, the type of the object,=20
>> and the phases of the moons of Saturn.  For instance, since I use OS X,=
>=20
>> my id()s are very small (and they fit in short-term memory).
>
>I don't depend on them, I just want to show them in hex in my __repr__,
>so that I can see two objects are equal.
>
>> Obj uses %p in it's __repr__ function, which is implemented in C, not=20
>> Python.  It doesn't even call id().
>>=20
>> My question is why you implement __repr__, when you get object's=20
>> behavior for free.
>
>Because I want to include more information.
>
>My code really is:
>
>    def __repr__(self):
>        s =3D "<%s sprite(in %d groups) at %x pos=3D%s>"
>        return s % (self.__class__.__name__, len(self.__g), \
>                    id(self), self.rect.topleft)
>
>...and the base class happens to define __repr__, which does not include
>id(self). I want to be able to see in debugging code that a certain
>sprite at pos (x1, y1) at frame N is the same as a certain sprite at
>position (x2, y2) in frame M. id(self) seems ideal for that, until these
>Warnings started (I now do abs(id(self)), which is ugly enough but gets
>rid of the warning).
>
>Any hints on getting this right? Parsing object.__repr__(self) is not
>the best solution either ;-)
>
IMO the proposed "-"-prefixed-hex-of-the-absolute-value format is a disgusting
pustulent wart on python, and goes against all tradition in hex representation.
Hex is not primarily a radix matter IMO. It is a matter of showing information
in a format that maps well to bit vectors such as are used in hardware representations
of numbers _and_ other info such as boolean vectors or foreign data structures like
c-struct fields etc. I think this change is drifting towards an embarassment for python
and requires a midcourse corrective maneuver. IMHO. ;-) <flame shields up>

Hence I think the solution is a new alternative format for hex literals, not a trashing
of the utility of the current format. Several have been proposed. A post-fixed h or H
with infinite sign bit hex representation 0's or F's or f's collapsed to a single 0 or F or f
would seem simple enough. The binary version with post-fixed b and infinite sign bits
collapsed to a single 0 or 1 works nicely analogously, BTW.

(Not tested beyond what you see ;-)

 >>> def myhex(n):
 ...     ret = ['h']
 ...     while n and n!=-1:
 ...         ret.append('0123456789abcdef'[n&0xf])
 ...         n>>=4
 ...     ret.append(n<0 and 'f' or '0')
 ...     return ''.join(ret[::-1])
 ...
 >>> myhex(0)
 '0h'
 >>> myhex(1)
 '01h'
 >>> myhex(8)
 '08h'
 >>> myhex(-8)
 'f8h'
 >>> myhex(0x80000000L)
 '080000000h'
 >>> myhex(-0x80000000L)
 'f80000000h'
 >>> for i in xrange(-16,17): print '%4s%s'%(myhex(i),'\n'[:(i%16)==15]),
 ...
  f0h  f1h  f2h  f3h  f4h  f5h  f6h  f7h  f8h  f9h  fah  fbh  fch  fdh  feh   fh
   0h  01h  02h  03h  04h  05h  06h  07h  08h  09h  0ah  0bh  0ch  0dh  0eh  0fh
 010h

or for a brute force 8-digit thing for your __repr__ (untested):

def myhex(n): return ''.join(['0123456789ABCDEF'[(n>>i)&0xf] for i in xrange(28,-4,-4)])

Sorry, this roused my pet peeve (is there a cute graphic of this creature somewhere? ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list