Finding the name of a class

Discussion in 'Python' started by Kirk Strauser, Aug 1, 2006.

  1. Given a class:

    >>> class foo(object):
    >>> pass


    how can I find its name, such as:

    >>> b = foo
    >>> print something(b)

    '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.
    --
    Kirk Strauser
    Kirk Strauser, Aug 1, 2006
    #1
    1. Advertising

  2. Kirk Strauser wrote:
    > Given a class:
    >
    >>>> class foo(object):
    >>>> pass

    >
    > how can I find its name, such as:
    >
    >>>> b = foo


    I suppose you mean b = foo() ?

    >>>> print something(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.

    >>> class Foo(object):

    .... pass
    ....
    >>> b = Foo
    >>> b.__name__

    'Foo'
    >>> b = Foo()
    >>> b.__class__.__name__

    '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.


    >>> help(dir)

    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.

    >>>


    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
    Bruno Desthuilliers, Aug 1, 2006
    #2
    1. Advertising

  3. Kirk Strauser

    Larry Bates Guest

    Kirk Strauser wrote:
    > Given a class:
    >
    >>>> class foo(object):
    >>>> pass

    >
    > how can I find its name, such as:
    >
    >>>> b = foo
    >>>> print something(b)

    > '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
    Larry Bates, Aug 1, 2006
    #3
  4. Kirk Strauser

    Tim Chase Guest

    >>>> class Foo(object):
    > ... pass
    > ...
    >>>> b = Foo
    >>>> b.__name__

    > 'Foo'


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

    >>>> help(dir)

    > Help on built-in function dir in module __builtin__:


    continuing from your example...

    >>> dir(b)

    ['__class__', '__delattr__', '__dict__', '__doc__',
    '__getattribute__', '__hash__', '__init__', '__module__',
    '__new__', '__reduce__', '__reduce_ex__', '__repr__',
    '__setattr__', '__str__', '__weakref__']
    >>> '__name__' in dir(b)

    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
    Tim Chase, Aug 1, 2006
    #4
  5. Kirk Strauser

    John Salerno Guest

    Tim Chase wrote:

    > 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:

    >>> class Foo(object):

    pass

    >>> f = Foo()
    >>> f.__name__


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

    'Foo'
    John Salerno, Aug 1, 2006
    #5
  6. Larry Bates wrote:

    > 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:

    >>> from Daycos.TableCopier.copyfro import StateProcessor
    >>> print StateProcessor.__class__.__name__

    type

    I'm looking for something that would print 'StateProcessor' but am not
    having much luck.
    --
    Kirk Strauser
    Kirk Strauser, Aug 1, 2006
    #6
  7. Kirk Strauser

    John Salerno Guest

    John Salerno wrote:
    > Tim Chase wrote:
    >
    >> 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:


    On the other hand:

    >>> class Foo(object):

    pass

    >>> dir(Foo)

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



    Hmmm.....
    John Salerno, Aug 1, 2006
    #7
  8. Bruno Desthuilliers wrote:

    > Kirk Strauser wrote:


    >>>>> class foo(object):
    >>>>> pass

    >>
    >> how can I find its name, such as:
    >>
    >>>>> b = foo


    > 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:

    >>> class Foo(object):

    .... 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__

    <type 'instancemethod'>
    >>> b.__class__.__name__

    'instancemethod'

    I was sort of hoping that it would print 'Foo'.
    --
    Kirk Strauser
    Kirk Strauser, Aug 1, 2006
    #8
  9. John Salerno wrote:
    > >>> class Foo(object):

    > pass
    >
    > >>> dir(Foo)

    > ['__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
    Shane Hathaway, Aug 1, 2006
    #9
  10. Kirk Strauser

    Tim Chase Guest

    >> 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:


    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.

    >>> class Foo(object):

    .... pass
    ....
    >>> myClass = Foo
    >>> myInstance = Foo()
    >>> # does myClass have a '__name__' attribute?
    >>> '__name__' in dir(myClass)

    False
    >>> # that's a negative, buster
    >>> '__name__' in dir(myInstance)

    False
    >>> # haha, just kidding, it really did have a __name__
    >>> # proof that dir() isn't showing everything:
    >>> myClass.__name__

    'Foo'
    >>> myInstance.__name__

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: 'Foo' object has no attribute '__name__'


    It's the

    >>> '__name__' in dir(myClass)

    False
    >>> myClass.__name__

    'Foo'

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

    -a still-confused tkc
    Tim Chase, Aug 1, 2006
    #10
  11. Kirk Strauser

    John Salerno Guest

    Shane Hathaway wrote:

    > 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 Foo(object):

    pass

    >>> dir(Foo)

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

    >>> dir(Foo.__class__)

    ['__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']

    >>> class Foo:

    pass

    >>> dir(Foo)

    ['__doc__', '__module__']

    >>> dir(Foo.__class__)

    Traceback (most recent call last):
    File "<pyshell#9>", line 1, in -toplevel-
    dir(Foo.__class__)
    AttributeError: class Foo has no attribute '__class__'
    John Salerno, Aug 1, 2006
    #11
  12. 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:
    >
    > >>> class Foo(object):

    > ... def bar(self):
    > ... pass
    > ...
    > >>> b = Foo.bar


    >>> print b.im_class.__name__

    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
    Ziga Seilnacht, Aug 1, 2006
    #12
  13. On Tue, 01 Aug 2006 11:09:57 -0500, Kirk Strauser <>
    declaimed the following in comp.lang.python:

    >
    > 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__

    > <type 'instancemethod'>
    > >>> 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.

    >>> class Foo(object):

    .... def bar(self):
    .... print self.__class__.__name__
    ....
    >>> class Sna(object):

    .... pass
    ....
    >>> Sna.fu = Foo.bar
    >>>
    >>> s=Sna()
    >>> s.fu()

    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)
    >>> f=Foo()
    >>> f.bar()

    Foo
    >>> Sna.fu(f)

    Foo
    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
    Dennis Lee Bieber, Aug 1, 2006
    #13
  14. On Tue, 01 Aug 2006 10:56:52 -0500, Kirk Strauser <>
    declaimed the following in comp.lang.python:

    > Larry Bates wrote:
    >
    > > 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:
    >
    > >>> from Daycos.TableCopier.copyfro import StateProcessor
    > >>> print StateProcessor.__class__.__name__

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


    And what is "StateProcessor"

    >>> class SP(object):

    .... pass
    ....
    >>> print SP.__class__.__name__

    type
    >>>


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

    >>> s=SP()
    >>> print s.__class__.__name__

    SP
    >>> DP = SP
    >>> d = DP()
    >>> print DP.__class__.__name__

    type
    >>> print d.__class__.__name__

    SP
    >>>

    --
    Wulfraed Dennis Lee Bieber KD6MOG

    HTTP://wlfraed.home.netcom.com/
    (Bestiaria Support Staff: )
    HTTP://www.bestiaria.com/
    Dennis Lee Bieber, Aug 1, 2006
    #14
  15. Kirk Strauser

    Kent Johnson Guest

    Kirk Strauser wrote:
    > Larry Bates wrote:
    >
    >> 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:
    >
    >>>> from Daycos.TableCopier.copyfro import StateProcessor
    >>>> print StateProcessor.__class__.__name__

    > 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
    Kent Johnson, Aug 1, 2006
    #15
  16. Kirk Strauser

    Larry Bates Guest

    Dennis Lee Bieber wrote:
    > On Tue, 01 Aug 2006 10:56:52 -0500, Kirk Strauser <>
    > declaimed the following in comp.lang.python:
    >
    >> Larry Bates wrote:
    >>
    >>> 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:
    >>
    >>>>> from Daycos.TableCopier.copyfro import StateProcessor
    >>>>> print StateProcessor.__class__.__name__

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

    >
    > And what is "StateProcessor"
    >
    >>>> class SP(object):

    > ... pass
    > ...
    >>>> print SP.__class__.__name__

    > type
    >
    > Looks like it is, itself, the class, not something within the class.
    >
    >>>> s=SP()
    >>>> print s.__class__.__name__

    > SP
    >>>> DP = SP
    >>>> d = DP()
    >>>> print DP.__class__.__name__

    > type
    >>>> print d.__class__.__name__

    > 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
    Larry Bates, Aug 1, 2006
    #16
  17. Tim Chase a écrit :
    >>>>> class Foo(object):

    >>
    >> ... pass
    >> ...
    >>
    >>>>> b = Foo
    >>>>> b.__name__

    >>
    >> 'Foo'

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


    Mmm... Documentation needs update ?

    > >>>> help(dir)

    > > Help on built-in function dir in module __builtin__:

    >
    > continuing from your example...
    >
    > >>> dir(b)


    > ['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
    > '__hash__', '__init__', '__module__', '__new__', '__reduce__',
    > '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__']
    > >>> '__name__' in dir(b)

    > 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...
    bruno desthuilliers, Aug 1, 2006
    #17
  18. Kirk Strauser wrote:
    > Bruno Desthuilliers wrote:
    >
    >> Kirk Strauser wrote:

    >
    >>>>>> class foo(object):
    >>>>>> pass
    >>> how can I find its name, such as:
    >>>
    >>>>>> b = foo

    >
    >> 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,


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


    >> 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. :)


    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:
    >
    >>>> class Foo(object):

    > ... 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.im_class

    <class '__main__.Foo'>
    >>> b.im_class.__name__

    'Foo'
    >>>



    >>>> b.__class__


    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.


    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
    Bruno Desthuilliers, Aug 2, 2006
    #18
  19. Dennis Lee Bieber wrote:
    > On Tue, 01 Aug 2006 11:09:57 -0500, Kirk Strauser <>
    > declaimed the following in comp.lang.python:
    >
    >> 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.


    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__

    >> <type 'instancemethod'>
    >>>>> 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.


    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
    Bruno Desthuilliers, Aug 2, 2006
    #19
  20. Larry Bates wrote:
    > Kirk Strauser wrote:
    >> Given a class:
    >>
    >>>>> class foo(object):
    >>>>> pass

    >> how can I find its name, such as:
    >>
    >>>>> b = foo
    >>>>> print something(b)

    >> '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


    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).



    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
    Bruno Desthuilliers, Aug 2, 2006
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,736
    Thomas Weidenfeller
    Oct 12, 2005
  2. =?iso-8859-1?B?bW9vcJk=?=
    Replies:
    7
    Views:
    817
    Roedy Green
    Jan 2, 2006
  3. ding feng
    Replies:
    2
    Views:
    2,801
    ding feng
    Jun 25, 2003
  4. Edward C. Jones

    Finding the name of a class

    Edward C. Jones, May 13, 2004, in forum: Python
    Replies:
    5
    Views:
    471
    Thomas Philips
    May 13, 2004
  5. Bobby Chamness
    Replies:
    2
    Views:
    2,387
    Joe Smith
    Apr 22, 2007
Loading...

Share This Page