How to obtain an instance's name at runtime?

Steven D. Majewski sdm7g at Virginia.EDU
Sat Jun 26 02:02:01 CEST 1999


On Fri, 25 Jun 1999, Dinu C. Gherman wrote:

> In article <3771127C.E40F9BF3 at home.com>,
>   Jim Meier <fatjim at home.com> wrote:
> >
> > Well, there sort of is a solution, but I don't think you're going
> > to like it. Incidentally, why are you trying to discover this? I'm
> > not a super-meister-coder, but I can't imagine a situation where
> > knowing this would be useful.
> 
> Ok, I knew I was going to look like a dumb camel right after
> posting my question... Nevertheless there is a useful case of
> knowing such an instance's name, at least I believe I found
> one. Have a look at the following page, spot the question mark
> and you'll know what I mean:
> 
>   http://starship.python.net/crew/gherman/UMLgenTest.pdf
> 
> But, PLEASE, don't start to ask me anything about the project
> itself!! It's all in a very pre-pre-pre-alpha phase...
> 
> There might be some workaround solution in oder to get that
> name I want, as in some of the replied in this thread, but
> I'll evaluate that later...


It's easy to get *A* name -- 

 Classes and functions have cannonical names in Python because Python
distinguishes between definition and assignment for classes and
functions. They also have a cannonical namespace -- for classes,
their __module__ attribute, for Python functions, their func_globals
attribute (which is the __dict__ of the __module__ they were defined
in.)  That's why their names are "sticky" . 

 Classes and functions can be aliased and assigned to other names,
but for debugging, tracebacks and printing, you want that cannonical
defining name. 

 There are other types of objects that could benefit from "sticky" 
names: constants and enumns for example. But Python doesn't 
have a different syntax to indicate a definition separate from 
any other assignment. 


You can get a name by searching for the thing in all of the namespaces:

>>> def findname(thing):
... 	for mod in sys.modules.values():
... 		for name,val in mod.__dict__.items():
... 			if val is thing : return name 

>>> findname( sys.stdin )
'stdin'
>>> findname( findname )
'findname'

>>> findname( lambda x: x+1 )	# anonymous function doesn't have a name 
				# returns None 

>>> xxx = sys.stdin		# alias sys.stdin to another name
>>> findname( sys.stdin )	# finds *a* name (whichever is first)
'xxx'


# Try the __name__ attribute first before searching... 

>>> def nameof( THING ):
... 	return getattr( THING, '__name__', None ) or findname( THING )
... 


>>> nameof( lambda x: x+1 )
'<lambda>'
>>> mod = sys
>>> nameof( mod )
'sys'
 

[1] You could do a smarter seach of the name space, but I'm not sure
if that would be any better for your application.

[2] You could also append the module name to the name and return 
  "sys.stdin" rather than "stdin" above. 

[3] Might there be cases where you want the '__repr__' rather than
 the name ?  i.e. "<open file '<stdin>', mode 'r' at 5a28500>" rather
 than "stdin" 



---|  Steven D. Majewski   (804-982-0831)  <sdm7g at Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---

 "IA-64 looks just about like what you would expect from a PA-RISC
  and IA-32 train wreck with a little VLIW thrown in for spice."
 * Thomas J. Merritt  <tjm at spam.codegen.com> in <news:comp.arch> *





More information about the Python-list mailing list