I think you are confused that although all Python variables can be objects, and all the properties of these variables can be objects, there is a limit. I mean, for a regular class, a structure usually goes:
myclass -> classobj -> type
which you can see if you try this in the console:
>> class A: .. pass .. >> print type(A) <type 'classobj'> >> print type(type(A)) <type 'type'>
but if you try to go deeper than type , you just get type . type is the base object for all objects in Python.
>> print type(type(type(A))) <type 'type'> >> print type(type(type(type(type(A))))) <type 'type'>
You get not only the same base class / object type, but you get the same instance of this type for an instance of class A, therefore, although you can do an infinite recursion of the type function (i.e. type(type(type(type(... )))) ), you won’t go anywhere (that is, you will not explore the bottomless pit of infinite memory).
>> id(type(type(type(A))) 505578544 >> id(type(type(type(type(A)))) 505578544
The same principle applies to all objects in Python and all properties of objects in Python, since they are also objects, but they are all finite.
Answering one of your previous questions,
foo.__call__ is the same instance of the wrapper method as foo.__call__.__call__
So, nothing prevents you from making a very long line with foo.__call__.__call__.__call__ ...
Python plays the trick with you in that foo.__call__ provides an instance for the wrapper method, and inside this wrapper method class there is a function / variable, also called __call__ , which points to the same instance of this class.