class A:
def __init__(self):
print(__class__) # -> A
print(self.__class__) # -> A
A()
I didn’t know that it worked!
Why can __class__ attribute be accessed without an instance, exceptionally? Why cannot other attributes such as __mro__, __dict__, __module__, etc.?
I tried to search on google but I couldn’t find any information…
There’s a subtle difference between __class__ and self.__class__: the former is the class that this function is defined in, and is necessary for the zero-argument form of super(). In Python 2, this feature didn’t exist, and the only way to call super was to do something like super(A, self) - in Python 3, the no-arg form super() is equivalent to super(__class__, self) where self really is “the first positional argument to this function”.
So if you want to know about the actual type of the object you’re working with, self.__class__ (or type(self) which does a similar job) will do that, but to refer to the class that this method was defined in - rare other than for calling super() - use __class__ on its own.