== An operational explanation of Python types In the world of new style classes, everything in Python has a type (visible with '_type(thing)_'); class instances have a type, [[classes have a type ClassesAndTypes]], even _type()_ has itself as a type. Sure, fine, but what does it mean in Python to have a type? What do types actually *do*? Given [[part 4 of what you can do with metaclasses UsingMetaclass04]], we can now see the answer: ~~an object's type is where Python finds special methods for it~~. Python does not look for special methods through the normal attribute lookup process (where it would effectively look up ((obj.__str__)) if you did _str(obj)_); instead it goes straight to the type (doing the equivalent of _``type(obj).__str__''_). Here, let's have an example: > class Example(object): > def __str__(self): > return "class" > > ei = Example() > ei.__str__ = lambda x: "lambda" > print ei.__str__(ei), str(ei) This will print '_lambda class_', showing that _str()_ is not using the version of ((__str__)) on the object itself. Now we can see why everything in Python has the type that it does. Instances of a class have a _type()_ of their class so that special methods are looked up on their class, which lets classes actually implement all of those special methods. Classes have a _type()_ of their metaclass (or _type_ if they have no metaclass) so that things like ((__call__)) get looked up on their metaclass (or on _type_ itself, which has the standard implementation of various things). Both _type_ and _object_ have the type of _type_ for the same reason (well, in theory). (My example above was contrived because people generally don't try to put special methods on instances. But it's easy to have a clash between a class special method and a metaclass special method, and then this does matter.) One of the nice aspects of this is that it unifies how Python does attribute lookup for instances of classes with how it does it with classes. There is no special magic in the interpreter to treat them differently; how they behave is just determined by how their type acts. Much of what looks like fundamental behavior (such as using '_Example()_' to create an instance of the class) is in fact simply due to how _object_ and _type_ act. Types also get involved in explicit attribute lookups, but that's a much more complicated topic and is not as core to what a type is in Python. (Well, in my opinion.)