1980

How do I find out the name of the class used to create an instance of an object in Python?

I'm not sure if I should use the inspect module or parse the __class__ attribute.

2
  • What exactly are you 'parsing' from the class variable?
    – sykora
    Commented Feb 4, 2009 at 11:49
  • 3
    the top-level name of the class that the instance belongs to (without module name, etc...)
    – Dan
    Commented Feb 4, 2009 at 11:50

12 Answers 12

2565

Have you tried the __name__ attribute of the class? ie type(x).__name__ will give you the name of the class, which I think is what you want.

>>> import itertools
>>> x = itertools.count(0)
>>> type(x).__name__
'count'

If you're still using Python 2, note that the above method works with new-style classes only (in Python 3+ all classes are "new-style" classes). Your code might use some old-style classes. The following works for both:

x.__class__.__name__
11
  • 52
    Amazingly simple. Wonder why dir(x.__class__) does not list it?
    – cfi
    Commented Jan 21, 2013 at 10:40
  • 55
    Why use __class__ over the type method? Like so: type(x).__name__. Isn't calling double underscore members directly discouraged? I can't see a way around using __name__, though.
    – jpmc26
    Commented Mar 7, 2013 at 20:41
  • 27
    You have to use __class__ directly to be compatible with old-style classes, since their type is just instance.
    – Quantum7
    Commented Aug 7, 2013 at 19:50
  • 28
    This is used often enough in logging, orm and framework code that there really should be a builtin typename(x) ... requiring a user to look at the "guts" to get a name isn't terribly pythonic, IMO. Commented Apr 18, 2018 at 13:19
  • 9
    @ErikAronesty, def typename(x): return type(x).__name__
    – sleblanc
    Commented Aug 12, 2018 at 22:07
557

Do you want the name of the class as a string?

instance.__class__.__name__
8
  • 9
    Or instance.__class__ to get the class object :D Commented May 28, 2013 at 11:15
  • 9
    Is it safe to use double underscore properties? Commented Sep 5, 2014 at 11:11
  • 7
    @EduardLuca why wouldn't it be safe? Built-in properties use underscores so that they do not cause any conflict with the code you write
    – user4396006
    Commented Jul 10, 2015 at 20:48
  • 3
    Well I know that single underscores mean / suggest that the method / property should be private (although you can't really implement private methods in Python AFAIK), and I was wondering if that's not the case with (some) double underscores too. Commented Jul 13, 2015 at 9:07
  • 47
    @EduardLuca Double underscores at the start only are similar to a single underscore at the start, but even more "private" (look up "python name mangling"). Double underscores at beginning and end are different - those are reserved for python and are not private (e.g. magic methods like __init__ and __add__). Commented Aug 10, 2015 at 22:33
184

type() ?

>>> class A:
...     def whoami(self):
...         print(type(self).__name__)
...
>>>
>>> class B(A):
...     pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>
5
  • 13
    I like this one. This way, it is possible in a base class to get the name of the subclass.
    – joctee
    Commented Jun 4, 2012 at 11:43
  • 17
    or self.__class__.__name__ instead of type(self).__name__ to get the same behaviour. Unless there is something the type() function does that I am not aware of?
    – andreb
    Commented Aug 20, 2012 at 21:47
  • 3
    If you're using type(item) on a list item the result will be <type 'instance'> while item.__class__.__name__ holds the class name.
    – Grochni
    Commented Aug 6, 2014 at 9:43
  • 1
    I think the issue that @Grochni mentions is only relevant for certain classes in Python 2.x, see here: stackoverflow.com/questions/6666856/…
    – Nate C-K
    Commented Feb 22, 2015 at 18:09
  • @andreb The original solution is shorter.
    – OrrinPants
    Commented Mar 8, 2023 at 15:27
53
class A:
  pass

a = A()
str(a.__class__)

The sample code above (when input in the interactive interpreter) will produce '__main__.A' as opposed to 'A' which is produced if the __name__ attribute is invoked. By simply passing the result of A.__class__ to the str constructor the parsing is handled for you. However, you could also use the following code if you want something more explicit.

"{0}.{1}".format(a.__class__.__module__,a.__class__.__name__)

This behavior can be preferable if you have classes with the same name defined in separate modules.

The sample code provided above was tested in Python 2.7.5.

0
30

In Python 2,

type(instance).__name__ != instance.__class__.__name__
# if class A is defined like
class A():
   ...

type(instance) == instance.__class__
# if class A is defined like
class A(object):
  ...

Example:

>>> class aclass(object):
...   pass
...
>>> a = aclass()
>>> type(a)
<class '__main__.aclass'>
>>> a.__class__
<class '__main__.aclass'>
>>>
>>> type(a).__name__
'aclass'
>>>
>>> a.__class__.__name__
'aclass'
>>>


>>> class bclass():
...   pass
...
>>> b = bclass()
>>>
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.bclass at 0xb765047c>
>>> type(b).__name__
'instance'
>>>
>>> b.__class__.__name__
'bclass'
>>>
1
  • 6
    This only holds true for old Python 2.x. In 3.x, bclass() would resolve to bclass(object). And even then, new classes appeared in Python 2.2.
    – alcalde
    Commented Sep 19, 2013 at 3:56
25

Alternatively you can use the classmethod decorator:

class A:
    @classmethod
    def get_classname(cls):
        return cls.__name__

    def use_classname(self):
        return self.get_classname()

Usage:

>>> A.get_classname()
'A'
>>> a = A()
>>> a.get_classname()
'A'
>>> a.use_classname()
'A'
0
18

Apart from grabbing the special __name__ attribute, you might find yourself in need of the qualified name for a given class/function. This is done by grabbing the types __qualname__.

In most cases, these will be exactly the same, but, when dealing with nested classes/methods these differ in the output you get. For example:

class Spam:
    def meth(self):
        pass
    class Bar:
        pass

>>> s = Spam()
>>> type(s).__name__ 
'Spam'
>>> type(s).__qualname__
'Spam'
>>> type(s).Bar.__name__       # type not needed here
'Bar'
>>> type(s).Bar.__qualname__   # type not needed here 
'Spam.Bar'
>>> type(s).meth.__name__
'meth'
>>> type(s).meth.__qualname__
'Spam.meth'

Since introspection is what you're after, this is always you might want to consider.

3
17

Good question.

Here's a simple example based on GHZ's which might help someone:

>>> class person(object):
        def init(self,name):
            self.name=name
        def info(self)
            print "My name is {0}, I am a {1}".format(self.name,self.__class__.__name__)
>>> bob = person(name='Robert')
>>> bob.info()
My name is Robert, I am a person
10

You can simply use __qualname__ which stands for qualified name of a function or class

Example:

>>> class C:
...     class D:
...         def meth(self):
...             pass
...
>>> C.__qualname__
'C'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__qualname__
'C.D.meth'

documentation link qualname

2
  • 2
    this gives the name of a class not the class name of an instance Commented Jan 21, 2021 at 17:54
  • 1
    This was already suggested by @Dimitris in 2017
    – Rimov
    Commented Feb 16, 2023 at 22:22
8

To get instance classname:

type(instance).__name__

or

instance.__class__.__name__

both are the same

1
1

You can first use type and then str to extract class name from it.

class foo:pass;

bar:foo=foo();
print(str(type(bar))[8:-2][len(str(type(bar).__module__))+1:]);

Result

foo
3
  • That's hard to read, are those inline methods I don't know about?
    – OrrinPants
    Commented Mar 8, 2023 at 15:36
  • If I came across a line such as this, I'd definitely "annotate" the code just to know the name of whom I was going to swear a lot. Commented Aug 31, 2023 at 19:39
  • Or just use type(bar).__qualname__
    – Oliver
    Commented Jul 9 at 8:10
0

If you're looking to solve this for a list (or iterable collection) of objects, here's how I would solve:

from operator import attrgetter

# Will use a few data types to show a point
my_list = [1, "2", 3.0, [4], object(), type, None]

# I specifically want to create a generator
my_class_names = list(map(attrgetter("__name__"), map(type, my_list))))

# Result:
['int', 'str', 'float', 'list', 'object', 'type', 'NoneType']


# Alternatively, use a lambda
my_class_names = list(map(lambda x: type(x).__name__, my_list))

Not the answer you're looking for? Browse other questions tagged or ask your own question.