Getting the class name of an instance?

1,277,268

Solution 1

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__

Solution 2

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

instance.__class__.__name__

Solution 3

type() ?

>>> class A:
...     def whoami(self):
...         print(type(self).__name__)
...
>>>
>>> class B(A):
...     pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>

Solution 4

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.

Solution 5

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'
>>>
Share:
1,277,268
Dan
Author by

Dan

-

Updated on January 22, 2021

Comments

  • Dan
    Dan over 3 years

    How do I find out a name of class that created an instance of an object in Python if the function I am doing this from is the base class of which the class of the instance has been derived?

    Was thinking maybe the inspect module might have helped me out here, but it doesn't seem to give me what I want. And short of parsing the __class__ member, I'm not sure how to get at this information.

    • sykora
      sykora over 15 years
      What exactly are you 'parsing' from the class variable?
    • Dan
      Dan over 15 years
      the top-level name of the class that the instance belongs to (without module name, etc...)
  • joctee
    joctee about 12 years
    I like this one. This way, it is possible in a base class to get the name of the subclass.
  • andreb
    andreb almost 12 years
    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?
  • cfi
    cfi over 11 years
    Amazingly simple. Wonder why dir(x.__class__) does not list it?
  • jpmc26
    jpmc26 over 11 years
    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.
  • Pencilcheck
    Pencilcheck about 11 years
    Or instance.__class__ to get the class object :D
  • Quantum7
    Quantum7 almost 11 years
    You have to use __class__ directly to be compatible with old-style classes, since their type is just instance.
  • alcalde
    alcalde almost 11 years
    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.
  • Grochni
    Grochni almost 10 years
    If you're using type(item) on a list item the result will be <type 'instance'> while item.__class__.__name__ holds the class name.
  • Eduard Luca
    Eduard Luca almost 10 years
    Is it safe to use double underscore properties?
  • Nate C-K
    Nate C-K over 9 years
    I think the issue that @Grochni mentions is only relevant for certain classes in Python 2.x, see here: stackoverflow.com/questions/6666856/…
  • Admin
    Admin almost 9 years
    @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
  • Eduard Luca
    Eduard Luca almost 9 years
    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.
  • Leagsaidh Gordon
    Leagsaidh Gordon almost 9 years
    @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__).
  • FireAphis
    FireAphis over 6 years
    Should be noted that __qualname__ is for Python 3.3+
  • Bobort
    Bobort about 6 years
    Since I'm using this is in a __getattr__ method, if I seek any attributes on self, I get a recursion error. Using type was of utmost importance in that situation.
  • Bobort
    Bobort about 6 years
    And I would avoid naming anything in my software "meth".
  • Erik Aronesty
    Erik Aronesty about 6 years
    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.
  • sleblanc
    sleblanc almost 6 years
    @ErikAronesty, def typename(x): return type(x).__name__
  • Bostone
    Bostone over 4 years
    Or if you doing this from inside the class this will work self.__class__.__name__
  • inVader
    inVader over 4 years
    So, I have tried both these solutions on a case where they do not perform as I would expect or wish. RandomOverSampler from the imblearn package is a class deriving from a series of parents where one of which is defined as SamplerMixin(BaseEstimator, metaclass=ABCMeta). In this case, both of the proposed methods return ABCMeta on an instance of RandomOverSampler (or the analogous RandomUnderSampler class) while I was looking for a convenient way to distinguish between these objects at runtime. Any idea on how to get the actual class name?
  • ti7
    ti7 over 4 years
    Related explanation for __qualname__ vs __name__: stackoverflow.com/questions/58108488/what-is-qualname-in-pyt‌​hon
  • wjandrea
    wjandrea almost 4 years
  • wjandrea
    wjandrea almost 4 years
    @Bobort Couldn't you just use super().__getattr__(self, '__class__')?
  • wjandrea
    wjandrea almost 4 years
    Actually they can be different if the class overrides __class__, or in old style classes (which are obsolete)
  • pascal sautot
    pascal sautot over 3 years
    this gives the name of a class not the class name of an instance
  • Roy Cohen
    Roy Cohen over 2 years
    @Bobort I remember reading somewhere that, for efficiency, dunder attributes don't work with custom __getattr__, so you wouldn't get a recursion error. Not sure tho.