Getting the class name of an instance?
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'
>>>
Comments
-
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 over 15 yearsWhat exactly are you 'parsing' from the class variable?
-
Dan over 15 yearsthe top-level name of the class that the instance belongs to (without module name, etc...)
-
-
joctee about 12 yearsI like this one. This way, it is possible in a base class to get the name of the subclass.
-
andreb almost 12 yearsor
self.__class__.__name__
instead oftype(self).__name__
to get the same behaviour. Unless there is something thetype()
function does that I am not aware of? -
cfi over 11 yearsAmazingly simple. Wonder why
dir(x.__class__)
does not list it? -
jpmc26 over 11 yearsWhy use
__class__
over thetype
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 about 11 yearsOr instance.__class__ to get the class object :D
-
Quantum7 almost 11 yearsYou have to use
__class__
directly to be compatible with old-style classes, since their type is justinstance
. -
alcalde almost 11 yearsThis 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 almost 10 yearsIf you're using
type(item)
on a list item the result will be<type 'instance'>
whileitem.__class__.__name__
holds the class name. -
Eduard Luca almost 10 yearsIs it safe to use double underscore properties?
-
Nate C-K over 9 yearsI think the issue that @Grochni mentions is only relevant for certain classes in Python 2.x, see here: stackoverflow.com/questions/6666856/…
-
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 almost 9 yearsWell 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 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 over 6 yearsShould be noted that
__qualname__
is for Python 3.3+ -
Bobort about 6 yearsSince I'm using this is in a
__getattr__
method, if I seek any attributes onself
, I get a recursion error. Usingtype
was of utmost importance in that situation. -
Bobort about 6 yearsAnd I would avoid naming anything in my software "meth".
-
Erik Aronesty about 6 yearsThis 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 almost 6 years@ErikAronesty,
def typename(x): return type(x).__name__
-
Bostone over 4 yearsOr if you doing this from inside the class this will work
self.__class__.__name__
-
inVader over 4 yearsSo, I have tried both these solutions on a case where they do not perform as I would expect or wish.
RandomOverSampler
from theimblearn
package is a class deriving from a series of parents where one of which is defined asSamplerMixin(BaseEstimator, metaclass=ABCMeta)
. In this case, both of the proposed methods returnABCMeta
on an instance ofRandomOverSampler
(or the analogousRandomUnderSampler
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 over 4 yearsRelated explanation for
__qualname__
vs__name__
: stackoverflow.com/questions/58108488/what-is-qualname-in-python -
wjandrea almost 4 years@jpmc26 They can be different.
-
wjandrea almost 4 years@Bobort Couldn't you just use
super().__getattr__(self, '__class__')
? -
wjandrea almost 4 yearsActually they can be different if the class overrides
__class__
, or in old style classes (which are obsolete) -
pascal sautot over 3 yearsthis gives the name of a class not the class name of an instance
-
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.