2

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?

Gerges
  • 6,269
  • 2
  • 22
  • 44
  • `a = A()` and `print(a.__class__.__name__)` ... `'A'` - `class P: pass` ... `print(P.__class__.__name__)` is `type` and `P` if you use the instance ... seems legit – Patrick Artner Jan 02 '19 at 16:46
  • Oh, yes that works. Is there a way to get the class name without instantiating it, and without using `__mro__`? – Gerges Jan 02 '19 at 16:48
  • 2
    use `A.__name__` ? – Patrick Artner Jan 02 '19 at 16:48
  • Ahh.. Thats exactly what I was missing. Not sure how i missed that. Feel free to write this as the answer. – Gerges Jan 02 '19 at 16:50
  • 2
    Because the *class of A* is the metaclass. So the *name* will be meta. A class object is an instance like any other, so just as if you did `a = A()` and `a.__class__.__name__` will give you `A` – juanpa.arrivillaga Jan 02 '19 at 16:51

2 Answers2

6

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.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

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)

jsbueno
  • 99,910
  • 10
  • 151
  • 209