Determining names of instances
Nick Mathewson
nickm at mit.edu
Mon Jan 15 23:39:47 EST 2001
On Mon, 15 Jan 2001 14:42:52 -0800, Daniel Klein <DanielK at jBASE.com> wrote:
>A question I hope has a simple answer. Take the following simple class and
>instance
>
> class foobar:
> pass
>
> foo = foobar()
>
>The question is, is there a way for the object 'foo' to know that its name
>is 'foo'?
>
>Daniel Klein
The short answer has been provided by others: not really.
The long answer is: yes, but you wouldn't want to.
# varname.py
from types import *
import sys
# We need python 2
assert sys.version_info[0] >= 2
def varname(object,depth):
try:
raise ""
except:
frame = sys.exc_traceback.tb_frame.f_back
seen={}
refs = [lr[1:] for lr in _searchInDict(object,
frame.f_locals,
depth,
seen,
1) ]
if frame.f_globals is not frame.f_locals:
refs += [gr[1:] for gr in _searchInDict(object,
frame.f_globals,
depth,
seen,
1) ]
return refs
def _search(obj, target, depth=1, seen=None):
if seen is None:
seen = {}
#if seen.get(id(target)):
# return ()
#seen[id(target)] = 1
if obj is target:
return [""]
if depth <= 0:
return []
t = type(target)
if t is ClassType:
return _searchInDict(obj, target.__dict__, depth, seen, 1)
elif t is DictType:
return _searchInDict(obj, target, depth, seen, 0)
elif t is InstanceType:
x = _searchInDict(obj, target.__dict__, depth, seen, 1)
return x+_searchInDict(obj,target.__class__.__dict__,depth,seen,1)
elif t in (ListType, TupleType):
return _searchInSeq(obj, target, depth, seen)
elif t is ModuleType:
return _searchInDict(obj, target.__dict__, depth, seen, 1)
return []
def _searchInDict(obj,dict,depth,seen,isAttr):
lst = []
for k,v in dict.items():
if v is obj:
lst.append( (isAttr and "."+k) or "[%s]"%`k` )
else:
for x in _search(obj,v,depth-1,seen):
lst.append( (isAttr and ".%s%s" %(k,x)) or "[%s]%s" %(`k`,x) )
return lst
def _searchInSeq(obj,seq,depth,seen):
lst = []
for i in range(len(seq)):
if seq[i] is obj:
lst.append( "["+i+"]")
elif depth:
for x in _search(obj,seq[i],depth-1,seen):
lst.append("["+i+"]"+x)
return lst
######
Use:
>>> from varname import varname
>>> x = "Hello world"
>>> varname(x, 1)
['x']
# Ok, that worked...
>>> p=y=t=h=o=n = x
>>> varname(x, 1)
['y', 't', 'p', 'n', 'o', 'h', 'x']
#... but what is the true name of 'x'?
>>> x = "Goodbye simplicity"
>>> varname(x, 6)
["sys.modules['__main__'].x", "sys.modules['sys'].modules['__main__'].x", 'x']
# ... and which of these is the name of 'x' now?
######
The moral is a corolary to Fredrik Lundh's cat analogy: Although your
neighbors (namespaces) can tell you the names they call the cat
(object), and although they can tell you what names that their friends
call the cat -- if you really want the cat (object) to have a name of its
own, you'll need to put a tag around its neck (set an attribute).
Too-much-time-on-my-hands-too-look-in-the-archive-ly y'rs,
--
Nick Mathewson <ZnickZm at alum.mit.edu> without the zees.
More information about the Python-list
mailing list