ChatGPT解决这个技术问题 Extra ChatGPT

Getting the class name of an instance

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.

What exactly are you 'parsing' from the class variable?
the top-level name of the class that the instance belongs to (without module name, etc...)

B
Boris Verkhovskiy

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__

Amazingly simple. Wonder why dir(x.__class__) does not list it?
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.
You have to use __class__ directly to be compatible with old-style classes, since their type is just instance.
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.
@ErikAronesty, def typename(x): return type(x).__name__
m
mthurlin

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

instance.__class__.__name__

Or instance.__class__ to get the class object :D
Is it safe to use double underscore properties?
@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
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.
@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__).
B
Boris Verkhovskiy

type() ?

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

I like this one. This way, it is possible in a base class to get the name of the subclass.
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?
If you're using type(item) on a list item the result will be <type 'instance'> while item.__class__.__name__ holds the class name.
I think the issue that @Grochni mentions is only relevant for certain classes in Python 2.x, see here: stackoverflow.com/questions/6666856/…
J
Jonathan
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.


w
wjandrea

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

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.
Y
Yurii Rabeshko

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'

R
RyanN

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

D
Dimitris Fasarakis Hilliard

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.


Should be noted that __qualname__ is for Python 3.3+
And I would avoid naming anything in my software "meth".
Related explanation for __qualname__ vs __name__: stackoverflow.com/questions/58108488/what-is-qualname-in-python
L
Lalit Vavdara

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


this gives the name of a class not the class name of an instance
v
v.babak

To get instance classname:

type(instance).__name__

or

instance.__class__.__name__

both are the same


Actually they can be different if the class overrides __class__, or in old style classes (which are obsolete)