Ian Bicking: the old part of his blog

Self Take Two

I presented a sort of Self-like system (in my mind), which I've been extending somewhat. Where that made all classes into instances, why not make all instances into classes? Then we get closer to what Self was doing.

This is done mostly in the metaclass, roughly like this:

class DeclarativeMeta(type):

    def __new__(meta, className, bases, d):
        cls = type.__new__(meta, className, bases, d)
        # We sometimes need access to an instance, not a class,
        # so we create one instance for the future:
        cls.instance = cls.__new__(cls)
        # I don't know quite why we need this, but we do:
        return cls

    def __call__(cls, **kw):
        Create a subclass of `cls`, given the new class variables
        name = 'Anonymous' + cls.__name__
        newCls = cls.__metaclass__.__new__(
            cls.__metaclass__, name, (cls,), kw)
        return newCls

This way you create new classes with each call, and each class only ever has one instance (it would be preferable if these two could be more closely conjoined, though). The parent/child relationship that Self uses exists through inheritance.

But are we back where we started, just adding some syntactic sugar to otherwise normal Python objects? The difference is that instead of instances belonging to classes, classes stand on their own -- classes are the instances. (Unfortunately we still keep an instance around, but that's just a hack)

I'm actually using this in FormEncode (which I'll release for real someday, really!), and it basically works. I use adaptation to grab the singleton when necessary (since I'm already using adaptation heavily, adding this extra step in is easy).

Created 13 Oct '03
Modified 14 Dec '04