Gerges
Gerges

Reputation: 6499

Getting the name of a class which has a meta class

Suppose I define a class A with a meta class like this:

class Meta(type):
    pass

class A(metaclass=Meta):
    pass

Then, when I try to access the name of class A I get the name of the meta class:

A.__class__.__name__
#  'Meta'

However, shouldn't it give me A, my defined class?

Note: I tried to use A.__mro__[0].__name__ and it does give me A, but I am still confused why A.__class__ gives me the meta class name. Does anyone has an explanation of this?

Upvotes: 2

Views: 2468

Answers (2)

jsbueno
jsbueno

Reputation: 110271

A is already the class - its name is under A.__name__. If you try A.__class__.__name__ you will get to the class of which A is instance (that is, its metaclass), name.

A.__mro__[0].__name__ will follow the "method resolution order" for the class A - the __mro__ object is a tuple with all the class hyerarchy that starts in the defined class itself and ends in object. So, A.__mro__[0] will always be A itself - and A.__mro__[0].__name__ is the same as A.__name__.

The __name__ and __qualname__ attributes are writable attributes: changing { __qualname__ after the class is created will change the default __repr__ for instances of that class, for example. Although they are in the language definition and "live" in slots in the class (not on it's dictionary), it is possible to create a __name__ property (I mean, the built-in property object, or any other descriptor) on the metaclass that will dynamically change the __name__ attribute of a class (but not __qualname__ - this must be an attribute of the class, and must be a string)

Upvotes: 1

Patrick Artner
Patrick Artner

Reputation: 51643

The __class__ dunder reports:

the class to which a class instance belongs.

Quote from instance.__class__

The class A belongs to the class of it's metaclass - only instances of A belong to the class A itself.

a = A() 
print(a.__class__.__name__) # 'A' 
print(A.__class__.__name__) # 'Meta'

class P: pass 

print(P.__class__.__name__) # type 
print(P().__class__.__name__) # P

To get the name of the class itself simply use

A.__name__

if you really need it.


I am still a way to groke all of answer to What are metaclasses in Python? - maybe it helps you out.

Upvotes: 7

Related Questions