[Python-Dev] New metaclass pattern (Was Re: Simulating Class (was Re: Does Python have Class methods)) (original) (raw)

Guido van Rossum guido@digicool.com
Wed, 23 May 2001 14:02:06 -0400


[this message has also been posted to comp.lang.python] [And I'm cc'ing there]

Guido's metaclass hook in Python goes this way:

If a base class (let's better call it a 'base object') has a class attribute, this is called to create the new class. >From demo/metaclasses/index.html: class C(B): a = 1 b = 2 Assuming B has a class attribute, this translates into: C = B.class('C', (B,), {'a': 1, 'b': 2})

Yes.

Usually B is an instance of a normal class.

No, B should behave like a class, which makes it an instance of a metaclass.

So the above code will create an instance of B, call B's init method with 'C', (B,), and {'a': 1, 'b': 2}, and assign the instance of B to the variable C.

No, it will not create an instance of B. It will create an instance of B.class, which is a subclass of B. The difference between subclassing and instantiation is confusing, but crucial, when talking about metaclasses! See the ASCII art in my classic post to the types-sig: http://mail.python.org/pipermail/types-sig/1998-November/000084.html

I've ever since played with this metaclass hook, and always found the problem that B would have to completely simulate the normal python behaviour for classes (modifying of course what you want to change).

The problem is that there are a lot of successful and unsucessful attribute lookups, which require a lot of overhead when implemented in Python: So the result is very slow (too slow to be usable in some cases).

Yes. You should be able to subclass an existing metaclass! Fortunately, in the descr-branch code in CVS, this is possible. I haven't explored it much yet, but it should be possible to do things like:

Integer = type(0) Class = Integer.class # same as type(Integer)

class MyClass(Class): ...

MyObject = MyClass("MyObject", (), {})

myInstance = MyObject()

Here MyClass declares a metaclass, and MyObject is a regular class that uses MyClass for its metaclass. Then, myInstance is an instance of MyObject.

See the end of PEP 252 for info on getting the descr-branch code (http://python.sourceforge.net/peps/pep-0252.html).

------

Python 2.1 allows to attach attributes to function objects, so a new metaclass pattern can be implemented. The idea is to let B be a function having a class attribute (which does not have to be a class, it can again be a function).

Oh, yuck. I suppose this is fine if you want to experiment with metaclasses in 2.1, but please consider using the descr-branch code instead so you can see what 2.2 will be like!

--Guido van Rossum (home page: http://www.python.org/~guido/)