[Tutor] inquire

Michael P. Reilly arcege@shore.net
Thu, 11 Jan 2001 13:19:56 -0500 (EST)


> Dear Sir/Madam,
> 
> Does python offer any method or function to return the name of any object?
> eg.
> 
> >>>aaa=None
> >>>print Wanted_Function(aaa)
> 'aaa'
> 
> the question is if such a function like Wanted_Function() actually exists.
> 
> Many Thanks,
> Xia XQ

Not easily, no.  As D-Man was referring to, Python is not a variable-
based language, but a name-binding one (that is why there is no pointer
dereferencing).

Take the following snippet:
>>> brunch = [ "eggs", "spam", "spam", "toast"]
>>> breakfast = brunch
>>> dinner = brunch; snack = breakfast
>>> brunch is breakfast
1
>>>

Which is the "name" of the list object: "brunch", "dinner", "snack" or
"breakfast"?  All the names are valid, is "brunch" the name because it
was first?  What about if the reference is in two modules for the same
object?

The best you could be hoping for is looking in the "current" namespace,
instead of having _one_ single name for an object.  It is best to use
the traceback and frame structure for this.  Here are some helper
functions to do this:

def get_frame():
  """Return the calling function's execution frame."""
  import sys  # import sys before the exception is raised
  try:
    raise Exception()
  except:
    exc, val, tb = sys.exc_info()
    frame_we_want = tb.tb_frame.f_back
    del tb # so we don't keep the reference to the traceback
    return frame_we_want

def Wanted_Name(findsym):
  frame = get_frame()
  # now we get the calling frame from here
  frame = frame.f_back

  # go through each name binding and see if it is the object
  # search globals, builtins and f_locals, in that order
  # do not search globals since it would likely be in the calling
  # function's locals anyway, and I'm guessing we want a more global name for it
  for namespace in ('f_globals', 'f_builtins', 'f_locals'):
    for (nam, obj) in getattr(frame, namespace).items():
      if findsym is obj:
        return nam
  # we didn't find it at all, could be in another module
  raise NameError(findsym)

if __name__ == '__main__':
  if Wanted_Name(get_frame) != 'get_frame'):
    raise SystemExit('It is not working, Arg!')

You might want to look at pdb and idle to see how those figure out this
problem.

Good luck,
  -Arcege


-- 
------------------------------------------------------------------------
| Michael P. Reilly, Release Manager  | Email: arcege@shore.net        |
| Salem, Mass. USA  01970             |                                |
------------------------------------------------------------------------