[Python-Dev] New metaclass pattern (Was Re: Simulating Class (was Re: Does Python have Class methods))
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/)