Suppose cls is a class in python. cls.__getattribute__ returns the __getattribute__ function defined on object, but it doesn't bind cls to this function. According to the descriptor protocol, cls is an instance of object and if an attribute is found on the class dictionary, it should return a bound method with cls bound to it.
The same call with cls.__call__ returns a bound method with cls bound to the __call__ function defined on type. Why is there a difference? Also why doesn't cls.__getattribute__ find the attribute in type?
class cls:
pass
[In]: cls.__getattribute__
[Out]: slot wrapper '__getattribute__' of 'object' objects>
[In]: object.__getattribute__
[Out]: <slot wrapper '__getattribute__' of 'object' objects>
[In]: cls.__getattribute__ is object.__getattribute__
[Out]: True
[In]: cls.__call__
[Out]: <method-wrapper '__call__' of type object at 0x7fdee07ad110>
[In]: type.__call__.__get__(cls)
[Out]: <method-wrapper '__call__' of type object at 0x7fdee07ad110>
When you look up
cls.__getattribute__, that gets found incls's own MRO, oncls's superclassobject. Like any other method found this way, the lookup returns an unbound method representing the__getattribute__method of instances of the class.On the other hand, when you look up
cls.__call__, that doesn't get found incls's MRO.cls's MRO is(cls, object), and neitherclsnorobjectdefines a__call__method. Instead, this method gets found oncls's own class, its metaclass: it gets found ontype. As with any other method found this way, the resulting method is bound to the instance the lookup happened on, that instance beingclsitself.Thus,
cls.__getattribute__represents the unbound method for getting attributes on instances ofcls, whilecls.__call__represents a bound method for callingclsitself.