Finding the name of a class

K

Kirk Strauser

Given a class:

how can I find its name, such as:
'foo'

I'm writing a trace() decorator for the sake of practice, and am trying to
print the name of the class that a traced method belongs to. This seems
like it should be easy, but I think I've been staring at the problem too
long.
 
B

Bruno Desthuilliers

Kirk said:
Given a class:


how can I find its name, such as:

I suppose you mean b = foo() ?

The name of a class is in the attribute '__name__' of the class. The
class of an object is in the attribute '__class__' of the object.
.... pass
....
I'm writing a trace() decorator for the sake of practice, and am trying to
print the name of the class that a traced method belongs to. This seems
like it should be easy, but I think I've been staring at the problem too
long.
Help on built-in function dir in module __builtin__:

dir(...)
dir([object]) -> list of strings

Return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it:

No argument: the names in the current scope.
Module object: the module attributes.
Type or class object: its attributes, and recursively the attributes of
its bases.
Otherwise: its attributes, its class's attributes, and recursively the
attributes of its class's base classes.
 
L

Larry Bates

Kirk said:
Given a class:


how can I find its name, such as:

'foo'

I'm writing a trace() decorator for the sake of practice, and am trying to
print the name of the class that a traced method belongs to. This seems
like it should be easy, but I think I've been staring at the problem too
long.

print print b.__class__.__name__ gives what you want

-Larry Bates
 
T

Tim Chase

class Foo(object):
... pass
...
'Foo'

While this is surely true, would somebody explain why I had such
trouble finding this?
> Help on built-in function dir in module __builtin__:

continuing from your example...
['__class__', '__delattr__', '__dict__', '__doc__',
'__getattribute__', '__hash__', '__init__', '__module__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', '__weakref__']False

'__name__' *really is* a method of b as shown by your example
lines, and can be successfully called. However, it *doesn't*
show up when asked for via dir(b). Grumble.

Is there a dir_and_i_really_mean_everything() function?

I suppose problems (mostly with expectations) can ensue when
you've got dynamic attributes, but this seems like something that
dir() should be finding.

-a puzzled tkc
 
J

John Salerno

Tim said:
While this is surely true, would somebody explain why I had such trouble
finding this?

I think __name__ is an attribute of the class itself, not the instance:

Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
f.__name__
AttributeError: 'Foo' object has no attribute '__name__''Foo'
 
K

Kirk Strauser

Larry said:
print print b.__class__.__name__ gives what you want

That doesn't seem to do it, though. Here's the result of importing a module
from my company's internally-developed library:
type

I'm looking for something that would print 'StateProcessor' but am not
having much luck.
 
J

John Salerno

John said:
I think __name__ is an attribute of the class itself, not the instance:
pass
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']



Hmmm.....
 
K

Kirk Strauser

Bruno said:
Kirk Strauser wrote:
I suppose you mean b = foo() ?

Actually, I meant 'b = foo' in this case - I want to find the name of the
class that b references, but the name of an instance (which may have zero
or many references to it).
The name of a class is in the attribute '__name__' of the class. The
class of an object is in the attribute '__class__' of the object.

I swear that didn't work earlier. Honest. :)

OK, now for the good stuff. In the code below, how can I find the name of
the class that 'bar' belongs to:
.... def bar(self):
.... pass
....
b = Foo.bar
dir(b) ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self']
b.__class__
b.__class__.__name__
'instancemethod'

I was sort of hoping that it would print 'Foo'.
 
S

Shane Hathaway

John said:
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']

Hmmm.....

Don't forget to file a bug.

Shane
 
T

Tim Chase

While this is surely true, would somebody explain why I had such trouble
I think __name__ is an attribute of the class itself, not the instance:

That makes sense, but what doesn't make sense is why, when you do
a dir(Foo), you don't get '__name__' in the returned list of
available things Python knows about a Foo.
.... pass
....Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'Foo' object has no attribute '__name__'


It's the
'Foo'

that throws me. What other super-secret tricks have I missed
because dir() didn't tell me about them?

-a still-confused tkc
 
J

John Salerno

Shane said:
Don't forget to file a bug.

I'm reluctant to call it a bug just yet. Here's more stuff below.
There's obviously a difference between old- and new-style classes. It
seems that as far as new-style is concerned, __name__ is an attribute of
__class__ (along with a bunch of other stuff), but not of Foo itself.


['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
['__base__', '__bases__', '__basicsize__', '__call__', '__class__',
'__cmp__', '__delattr__', '__dict__', '__dictoffset__', '__doc__',
'__flags__', '__getattribute__', '__hash__', '__init__', '__itemsize__',
'__module__', '__mro__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasses__',
'__weakrefoffset__', 'mro']
['__doc__', '__module__']
Traceback (most recent call last):
File "<pyshell#9>", line 1, in -toplevel-
dir(Foo.__class__)
AttributeError: class Foo has no attribute '__class__'
 
Z

Ziga Seilnacht

Kirk Strauser wrote:
[snip]
OK, now for the good stuff. In the code below, how can I find the name of
the class that 'bar' belongs to:

... def bar(self):
... pass
...
Foo


But if you are writing a decorator, you can use this code:

import sys

def tracer(func):
"""
A decorator that prints the name of the class from which it was
called.

The name is determined at class creation time. This works
only in CPython, since it relies on the sys._getframe()
function. The assumption is that it can only be called
from a class statement. The name of the class is deduced
from the code object name.
"""
classframe = sys._getframe(1)
print classframe.f_code.co_name
return func


Hope this helps,
Ziga
 
D

Dennis Lee Bieber

Actually, I meant 'b = foo' in this case - I want to find the name of the
class that b references, but the name of an instance (which may have zero
or many references to it).
Pardon... That gives the class object another name, neither of which
has any precedence over the other.
b = Foo.bar
dir(b) ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self']
b.__class__
b.__class__.__name__
'instancemethod'

I was sort of hoping that it would print 'Foo'.

But... you've just pulled the method "out" of the class
definition... Without supplying an instance, there is no linkage to a
class.
.... def bar(self):
.... print self.__class__.__name__
.... .... pass
.... Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: unbound method bar() must be called with Foo instance as
first argument (got nothing instead)Foo
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
D

Dennis Lee Bieber

That doesn't seem to do it, though. Here's the result of importing a module
from my company's internally-developed library:

type

I'm looking for something that would print 'StateProcessor' but am not
having much luck.

And what is "StateProcessor"
.... pass
....
Looks like it is, itself, the class, not something within the class.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
K

Kent Johnson

Kirk said:
That doesn't seem to do it, though. Here's the result of importing a module
from my company's internally-developed library:

type

I'm looking for something that would print 'StateProcessor' but am not
having much luck.

It looks like StateProcessor is a class; StateProcessor.__class__ is the
class of a class, i.e. type. Try
StateProcessor.__name__

Kent
 
L

Larry Bates

Dennis said:
And what is "StateProcessor"

... pass
...
type

Looks like it is, itself, the class, not something within the class.

SP

When I do this:

class foo(object):
pass

if __name__=="__main__":
a=foo()
print a.__class__.__name__


Note: You must do it on instance of the class not the class itself.

it prints 'foo' for me. Not exactly sure why you get something very
different. I've used this LOTS of times in my code, but I'll admit
mostly with old-style classes.

-Larry Bates
 
B

bruno desthuilliers

Tim Chase a écrit :
While this is surely true, would somebody explain why I had such trouble
finding this?

Mmm... Documentation needs update ?
continuing from your example...
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']False

'__name__' *really is* a method
s/method/attribute/

of b as shown by your example lines, and
can be successfully called. However, it *doesn't* show up when asked
for via dir(b). Grumble.

Yes, as mentionned in the doc, dir() doesn't list *all* names in a
namespace. DOn't ask me why nor how it chooses which ones it rejects, I
wonder too.
Is there a dir_and_i_really_mean_everything() function?

Perhaps in the inspect module...
 
B

Bruno Desthuilliers

Kirk said:
Actually, I meant 'b = foo' in this case - I want to find the name of the
class that b references,

Ok. Could have been a typo, just wanted to make sure.

I swear that didn't work earlier. Honest. :)

Not sure if it works for old-style classes...
OK, now for the good stuff. In the code below, how can I find the name of
the class that 'bar' belongs to:
... def bar(self):
... pass
...['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self']

This will give you the class of b itself. Remember that in Python,
everything and it's sister is an object - including functions, methods,
classes and modules.

In this case, b is a method object - IOW a descriptor that wraps a
function object.
 
B

Bruno Desthuilliers

Dennis said:
Pardon... That gives the class object another name, neither of which
has any precedence over the other.

Not quite exactly. The 'b = foo' statement binds together name b and the
object foo - which in this case happens to be a class. OTOH, class
objects do have a __name__ attribute, which is not impacted by the binding.
b = Foo.bar
dir(b)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class', 'im_func', 'im_self']
b.__class__
b.__class__.__name__
'instancemethod'

I was sort of hoping that it would print 'Foo'.

But... you've just pulled the method "out" of the class
definition... Without supplying an instance, there is no linkage to a
class.

Yes there is. Method objects have an im_class attribute, that is a
reference to the class they were 'pulled out' from.
 
B

Bruno Desthuilliers

Larry said:
print print b.__class__.__name__ gives what you want

Actually it should be b.__name__, since b refers to *class* foo.
b.__class__ is the metaclass (usually 'type' unless there's a custom
metaclass).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top