Wandering Thoughts archives


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, 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, 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.)

python/UnderstandingTypes written at 00:51:04; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.