473,406 Members | 2,356 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Inverse of id()?

Is there an inverse function to the builtin 'id'? The poster who
asked about 1-to-1, 1-to-n, etc. relationships (presumably in CS terms
- I hope I didn't misread some porn spam by mistake), got me thinking
about containers and ids, and what kind of a container would implement
a many-to-many.

I happened to still have my Python interpreter open from noodling
about another poster's question, using named arguments and parse-time
functions in a regex, so I looked at the 'results' variable that
experiment generated (this was a quick way to work with a non-trivial
object, so if I reconstructed it from an id, I could test whether I
really got back the object):
>>re = Regex("(\d*)").setResultsName("x").setParseAction( lambda t:int(t[0]))
results = re.parseString("123")
pyparsing results have some special lookup behavior, that if the
results name is a Python-friendly identifier, can use the name as if
it were an object attribute:
>>results.x
123

So I extracted the id of results, and then started looking for the
function that does the inverse of id. Unfortunately, skimming through
the docs, I didn't find it, so I brute-force searched the globals()
dict:
>>z = id(results)
for x in globals().values():
.... if id(x)==z: break
....

This gives me a variable x that is indeed another ref to the results
variable:
>>x is results
True
>>x.x
123

Now is there anything better than this search technique to get back a
variable, given its id?

-- Paul

May 19 '07 #1
10 4922
Paul McGuire <pt***@austin.rr.comwrote:
Is there an inverse function to the builtin 'id'? The poster who
No, there isn't.
Now is there anything better than this search technique to get back a
variable, given its id?
For your own classes/types, you could override __new__ to maintain a
class-wide (or even wider) weakref.WeakValueDictionary with id as the
key and the instance as the (weakly held) value. For the general case,
this wouldn't work -- however as your "search technique" checks globals
only, it's pretty weak (it wouldn't find a value that's only held as an
item in a list even if that list were global, for example). You might
do a bit better by checking through gc.get_objects(), but that won't get
objects of many types, such as int, float, str...
Alex
May 20 '07 #2
En Sat, 19 May 2007 20:42:53 -0300, Paul McGuire <pt***@austin.rr.com>
escribió:
>>>z = id(results)
for x in globals().values():
... if id(x)==z: break
...

This gives me a variable x that is indeed another ref to the results
variable:
>>>x is results
True
>>>x.x
123

Now is there anything better than this search technique to get back a
variable, given its id?
pyclass A:pass
....
pyclass B:pass
....
pya=A()
pyid(a)
10781400
pydel a
pyb=B()
pyid(b)
10781400

Now if you look for id=10781400 you'll find b, which is another,
absolutely unrelated, object.
Enabling this pointer -objects ability would bring into Python the "wild
pointer" nightmare of C programs...

--
Gabriel Genellina

May 20 '07 #3
Gabriel Genellina wrote:
En Sat, 19 May 2007 20:42:53 -0300, Paul McGuire <pt***@austin.rr.com>
escribió:
>>>>z = id(results)
for x in globals().values():
... if id(x)==z: break
...

This gives me a variable x that is indeed another ref to the results
variable:
>>>>x is results
True
>>>>x.x
123

Now is there anything better than this search technique to get back a
variable, given its id?

pyclass A:pass
...
pyclass B:pass
...
pya=A()
pyid(a)
10781400
pydel a
pyb=B()
pyid(b)
10781400

Now if you look for id=10781400 you'll find b, which is another,
absolutely unrelated, object.
That's not what I get:

Python 2.5 (r25:51908, Mar 13 2007, 08:13:14)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>class A: pass
....
>>class B: pass
....
>>a = A()
id(a)
2146651820
>>b = B()
id(b)
2146651948
--
Michael Hoffman
May 21 '07 #4
On 5/20/07, Michael Hoffman <ca*******@mh391.invalidwrote:
[snip]
That's not what I get:

Python 2.5 (r25:51908, Mar 13 2007, 08:13:14)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>class A: pass
...
>>class B: pass
...
>>a = A()
>>id(a)
2146651820
>>b = B()
>>id(b)
2146651948
--
Michael Hoffman
That's because you didn't have 'del a'.

Now I tried this in the shell and got different id's for a and b, but
when I typed it into a file and ran from there the id's where always
the same. Must have something to do with other programs allocating
space faster than I can type everything out (I do have a few processes
going). Interesting.

Ian
May 21 '07 #5
En Sun, 20 May 2007 22:19:01 -0300, Ian Clark <tu*****@gmail.comescribió:
On 5/20/07, Michael Hoffman <ca*******@mh391.invalidwrote:
> [snip]
That's not what I get:

That's because you didn't have 'del a'.

Now I tried this in the shell and got different id's for a and b, but
when I typed it into a file and ran from there the id's where always
the same. Must have something to do with other programs allocating
space faster than I can type everything out (I do have a few processes
going). Interesting.
The point is, as id() is related to the object memory address, and memory
may be reused, two objects (*NOT* simultaneously alive!!!) may return the
same id().
Perhaps in some circunstances it's easier to show than in others, but it
happens, so unless one is absolutely sure that the object is still alive,
going back from its id to the original object is dangerous.

--
Gabriel Genellina

May 21 '07 #6
"Ian Clark" <tu*****@gmail.comwrote:
Now I tried this in the shell and got different id's for a and b, but
when I typed it into a file and ran from there the id's where always
the same. Must have something to do with other programs allocating
space faster than I can type everything out (I do have a few processes
going). Interesting.
No, what other processes are doing isn't going to affect the memory
allocation within your Python process. More likely the interactive
interpreter is allocating or releasing other objects when it compiles
each line of input which stops you seeing the duplicated id. You can get
it to reuse the id by making sure you force everything to be compiled in
one go:
>>class A: pass
>>class B: pass
>>a = A();print id(a);del a;b = B();print id(b)
12948384
12948384
>>if 1:
a = A()
print id(a)
del a
b = B()
print id(b)
12948464
12948464
>>>
Gabriel's point however is not that this particular sequence will always
result in duplicate ids (it is just an artifact of the implementation
and could change), but that ids in general are re-used so any mapping
from id->object is ambiguous unless you can be certain that the object
whose id you took is still alive.

There are two common ways to do the reverse mapping: either store the
ids and objects in a dict thereby forcing the objects to continue to
exist, or store them in a weakref.WeakValueDictionary and be very
careful not to access an expired (and possibly reused) id.

For a completely safe technique which works with any weakly
referenceable object just ignore Python's id function and write your own
which never reuses an id. Then you can safely map from your own id
values back to the object if it still exists or get an exception if it
doesn't:
>>lastid = 0
idmap = weakref.WeakValueDictionary()
def myid(o):
global lastid
lastid += 1
idmap[lastid] = o
return lastid
>>def getfrommyid(id):
return idmap[id]
>>a = A()
print myid(a)
1
>>del a
b = B()
print myid(b)
2
>>print getfrommyid(2)
<__main__.B instance at 0x00CD43F0>
>>print getfrommyid(1)
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
print getfrommyid(1)
File "<pyshell#25>", line 2, in getfrommyid
return idmap[id]
File "C:\Python25\Lib\weakref.py", line 54, in __getitem__
o = self.data[key]()
KeyError: 1
>>>
Unfortunately that won't help with the common builtin objects as they
aren't weakly referenceable.
May 21 '07 #7
On 20 May, 01:42, Paul McGuire <p...@austin.rr.comwrote:
>
>re = Regex("(\d*)").setResultsName("x").setParseAction( lambda t:int(t[0]))
results = re.parseString("123")

pyparsing results have some special lookup behavior, that if the
results name is a Python-friendly identifier, can use the name as if
it were an object attribute:
>results.x
123
First of all, having recently looked at pyparsing again, I must say
that it's a nice framework for writing parsers quickly. Now I'm not
sure what the intention is behind this inquiry, so the following may
seem somewhat tangential, but one thing that I tend to do a lot with
pyparsing is to automatically set the results name by having a special
grammar object:

class Grammar:
def __setattr__(self, name, value):
self.__dict__[name] = Group(value.setResultsName(name))

This permits stuff like the following:

g = Grammar()
g.x = Regex("(\d*)").setParseAction(lambda t:int(t[0]))

You'd even be able to incorporate the parse action, too, with some
extra magic. As pyparsing is a library which seems to encourage clean
grammar definitions, I think this makes quite a difference, although I
now expect to be told that there's a class in the library which
supports this.

Anyway, back to the scheduled programme...

Paul

May 21 '07 #8
On May 21, 4:55 am, Paul Boddie <p...@boddie.org.ukwrote:
>
< some very kind comments re: pyparsing :) >

You'd even be able to incorporate the parse action, too, with some
extra magic. As pyparsing is a library which seems to encourage clean
grammar definitions, I think this makes quite a difference, although I
now expect to be told that there's a class in the library which
supports this.

Anyway, back to the scheduled programme...

Paul

Paul -

I'm glad pyparsing is working well for you. I've struggled with the
unwieldiness of setName and setResultsName since version 0.6 or so,
and yours is an interesting solution. This is definitely a case of
Python's __setAttr__ to the rescue. And, no there is nothing in
pyparsing that does anything like this, I think most people write
their own workarounds to this issue.

For instance, Seo Sanghyeon (I believe the same one now working on
IronPython) uses the following technique in the EBNF parser/"compiler"
that he contributed to the pyparsing examples directory:

# list of all the grammar variable names
all_names = '''
integer
meta_identifier
terminal_string
....
'''.split()

# parse actions follow
def do_integer(str, loc, toks):
return int(toks[0])

....

# now attach names and parse actions (and optionally set debugging)
for name in all_names:
expr = vars()[name]
action = vars()['do_' + name]
expr.setName(name)
expr.setParseAction(action)
#~ expr.setDebug()

This requires that you maintain the list of all_names, and it self-
imposes a naming standard for parse actions (which I am loath to
impose on others, in general).

Philosophically, though, there is a distinction between an
expression's name and its results name. I might define an integer and
use it many times within a grammar. All are named "integer" (as done
with setName), but I may wish to name the returned results with
different names (such as "age", "numberOfChildren", "birthYear",
etc.), and setResultsName performs this function.

I suppose I could add another operator, such as '/', so that something
like:

re = Regex("(\d*)").setParseAction(lambda t:int(t[0]))/"x"

would be equivalent to:

re = Regex("(\d*)").setParseAction(lambda
t:int(t[0])).setResultsName("x")

But this may be bordering on Perlishness, and it certainly is not as
explicit as "setResultsName" (there are also operator precedence
issues - note that I would need parens to use the '/' operator ahead
of '.setParseAction'). Now if the "as" keyword were opened up as a
customizable operator (__as__), *that* would fill the bill nicely, I
should think.

And finally, no, there is no hidden agenda at incorporating some form
of reverse id() lookup into pyparsing - I simply had an interpreter
open with some leftover pyparsing work in it, so it was a good source
of a non-trivial object that I could try to find, given its id.

-- Paul

May 21 '07 #9
Paul McGuire wrote:
For instance, Seo Sanghyeon (I believe the same one now working on
IronPython) uses the following technique in the EBNF parser/"compiler"
that he contributed to the pyparsing examples directory:

# list of all the grammar variable names
all_names = '''
integer
meta_identifier
terminal_string
...
'''.split()

# parse actions follow
def do_integer(str, loc, toks):
return int(toks[0])
FWIW, I find that my actions never use anything but the token list, so
to avoid writing a bunch of functions like the one above, I typically
write::

class ParseAction(object):
def __init__(self, func):
self.func = func
def __call__(self, string, index, tokens):
return self.func(*tokens)

...
# parse an integer
integer.addParseAction(ParseAction(int))
...
# parse a relation object, passing appropriate strings
# (or parsed objects) to the constructor
relation.setParseAction(ParseAction(Relation))

I guess the integer/int and relation/Relation is a little redundant, but
it's never bothered me too much.

STeVe
May 21 '07 #10
On May 21, 4:55 am, Paul Boddie <p...@boddie.org.ukwrote:
On 20 May, 01:42, Paul McGuire <p...@austin.rr.comwrote:
>>re = Regex("(\d*)").setResultsName("x").setParseAction( lambda t:int(t[0]))
>>results = re.parseString("123")
pyparsing results have some special lookup behavior, that if the
results name is a Python-friendly identifier, can use the name as if
it were an object attribute:
>>results.x
123

First of all, having recently looked at pyparsing again, I must say
that it's a nice framework for writing parsers quickly. Now I'm not
sure what the intention is behind this inquiry, so the following may
seem somewhat tangential, but one thing that I tend to do a lot with
pyparsing is to automatically set the results name by having a special
grammar object:

class Grammar:
def __setattr__(self, name, value):
self.__dict__[name] = Group(value.setResultsName(name))

This permits stuff like the following:

g = Grammar()
g.x = Regex("(\d*)").setParseAction(lambda t:int(t[0]))

You'd even be able to incorporate the parse action, too, with some
extra magic. As pyparsing is a library which seems to encourage clean
grammar definitions, I think this makes quite a difference, although I
now expect to be told that there's a class in the library which
supports this.

Anyway, back to the scheduled programme...

Paul
I'm considering adding a notational short-cut as an abbreviated
version of setResultsName(), in the next pyparsing release, described
here: http://pyparsing.wikispaces.com/mess...ew/home/606302
I propose we move the discussion of this idea to the pyparsing wiki,
so as not to (further?) clutter up c.l.py with this topic.

-- Paul

May 23 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: David C. Fox | last post by:
Is there a function which takes a list of tuples and returns a list of lists made up of the first element of each tuple, the second element of each tuple, etc.? In other words, the the inverse...
1
by: Andy | last post by:
I have drawn an icon. I used the the inverse color on the color window in order to get transparency. However, now the inverse color has stopped working by some reason. Why is this? I press and...
1
by: Richard Williamson | last post by:
Hi all, I am trying to create a query which will select the inverse of the records returned. Scenario: Member(MEMBERID,name, address,etc) Video(VIDEOID, title, certificate, etc.)...
6
by: vishnu mahendra | last post by:
hello to all, can any one please give me an algorithm to find inverse of a matrix of order n rows and m columns. thank you in advance, vishnu.
9
by: Water Cooler v2 | last post by:
What is the inverse of the sine function? I've been pulling my hair and I have no clue nor memory of how to go about solving this little expression: sine-1 (read sine inverse) of (1-(x/y)) An...
6
by: Randy | last post by:
Hello, Can someone tell me how to derive the Inverse of Math.Log10(value)? Thanks
3
by: Smokey Grindle | last post by:
How can you "inverse" a color in GDI+? Say the color I have is blue, the inverse of that is yellow... how would you go about doing this? is there a simpler way then taking the RGB values and...
4
by: Jonathan Fine | last post by:
Hello As part of the MathTran project I found myself wanting to maintain a bijection between long names and short names. http://www.open.ac.uk/mathtran In other words, I wanted to have two...
0
by: DarrenWeber | last post by:
# Copyright (C) 2007 Darren Lee Weber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.