blob: 378ceb3e2e7d79a1ac83af6ed8f8a2bbeb48c600 [file] [log] [blame]
Guido van Rossum1fb071c1997-08-25 21:36:44 +00001<HTML>
2
3<HEAD>
4<TITLE>Metaprogramming in Python 1.5</TITLE>
5</HEAD>
6
7<BODY BGCOLOR="FFFFFF">
8
9<H1>Metaprogramming in Python 1.5</H1>
10
11<H4>XXX Don't link to this page! It is very much a work in progress.</H4>
12
13<P>While Python 1.5 is only out as a <A
14HREF="http://grail.cnri.reston.va.us/python/1.5a3/">restricted alpha
15release</A>, its metaprogramming feature is worth mentioning.
16
17<P>In previous Python releases (and still in 1.5), there is something
18called the ``Don Beaudry hook'', after its inventor and champion.
19This allows C extensions to provide alternate class behavior, thereby
20allowing the Python class syntax to be used to define other class-like
21entities. Don Beaudry has used this in his infamous <A
22HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> package; Jim
23Fulton has used it in his <A
24HREF="http://www.digicool.com/papers/ExtensionClass.html">Extension
25Classes</A> package. (It has also been referred to as the ``Don
26Beaudry <i>hack</i>, but that's a misnomer. There's nothing hackish
27about it -- in fact, it is rather elegant and deep, even though
28there's something dark to it.)
29
30<P>Documentation of the Don Beaudry hook has purposefully been kept
31minimal, since it is a feature of incredible power, and is easily
32abused. Basically, it checks whether the <b>type of the base
33class</b> is callable, and if so, it is called to create the new
34class.
35
36<P>Note the two indirection levels. Take a simple example:
37
38<PRE>
39class B:
40 pass
41
42class C(B):
43 pass
44</PRE>
45
46Take a look at the second class definition, and try to fathom ``the
47type of the base class is callable.''
48
49<P>(Types are not classes, by the way. See questions 4.2, 4.19 and in
50particular 6.22 in the <A
51HREF="http://grail.cnri.reston.va.us/cgi-bin/faqw.py" >Python FAQ</A>
52for more on this topic.)
53
54<P>
55
56<UL>
57
58<LI>The <b>base class</b> is B; this one's easy.<P>
59
60<LI>Since B is a class, its type is ``class''; so the <b>type of the
61base class</b> is the type ``class''. This is also known as
62types.ClassType, assuming the standard module <code>types</code> has
63been imported.<P>
64
65<LI>Now is the type ``class'' <b>callable</b>? No, because types (in
66core Python) are never callable. Classes are callable (calling a
67class creates a new instance) but types aren't.<P>
68
69</UL>
70
71<P>So our conclusion is that in our example, the type of the base
72class (of C) is not callable. So the Don Beaudry hook does not apply,
73and the default class creation mechanism is used (which is also used
74when there is no base class). In fact, the Don Beaudry hook never
75applies when using only core Python, since the type of a core object
76is never callable.
77
78<P>So what do Don and Jim do in order to use Don's hook? Write an
79extension that defines at least two new Python object types. The
80first would be the type for ``class-like'' objects usable as a base
81class, to trigger Don's hook. This type must be made callable.
82That's why we need a second type. Whether an object is callable
83depends on its type. So whether a type object is callable depends on
84<i>its</i> type, which is a <i>meta-type</i>. (In core Python there
85is only one meta-type, the type ``type'' (types.TypeType), which is
86the type of all type objects, even itself.) A new meta-type must
87be defined that makes the type of the class-like objects callable.
88(Normally, a third type would also be needed, the new ``instance''
89type, but this is not an absolute requirement -- the new class type
90could return an object of some existing type when invoked to create an
91instance.)
92
93<P>Still confused? Here's a simple device due to Don himself to
94explain metaclasses. Take a simple class definition; assume B is a
95special class that triggers Don's hook:
96
97<PRE>
98class C(B):
99 a = 1
100 b = 2
101</PRE>
102
103This can be though of as equivalent to:
104
105<PRE>
106C = type(B)('C', (B,), {'a': 1, 'b': 2})
107</PRE>
108
109If that's too dense for you, here's the same thing written out using
110temporary variables:
111
112<PRE>
113creator = type(B) # The type of the base class
114name = 'C' # The name of the new class
115bases = (B,) # A tuple containing the base class(es)
116namespace = {'a': 1, 'b': 2} # The namespace of the class statement
117C = creator(name, bases, namespace)
118</PRE>
119
120This is analogous to what happens without the Don Beaudry hook, except
121that in that case the creator function is set to the default class
122creator.
123
124<P>In either case, the creator is called with three arguments. The
125first one, <i>name</i>, is the name of the new class (as given at the
126top of the class statement). The <i>bases</i> argument is a tuple of
127base classes (a singleton tuple if there's only one base class, like
128the example). Finally, <i>namespace</i> is a dictionary containing
129the local variables collected during execution of the class statement.
130
131<P>Note that the contents of the namespace dictionary is simply
132whatever names were defined in the class statement. A little-known
133fact is that when Python executes a class statement, it enters a new
134local namespace, and all assignments and function definitions take
135place in this namespace. Thus, after executing the following class
136statement:
137
138<PRE>
139class C:
140 a = 1
141 def f(s): pass
142</PRE>
143
144the class namespace's contents would be {'a': 1, 'f': &lt;function f
145...&gt;}.
146
147<P>But enough already about Python metaprogramming in C; read the
148documentation of <A
149HREF="http://maigret.cog.brown.edu/pyutil/">MESS</A> or <A
150HREF="http://www.digicool.com/papers/ExtensionClass.html" >Extension
151Classes</A> for more information.
152
153<H2>Writing Metaclasses in Python</H2>
154
155<P>In Python 1.5, the requirement to write a C extension in order to
156engage in metaprogramming has been dropped (though you can still do
157it, of course). In addition to the check ``is the type of the base
158class callable,'' there's a check ``does the base class have a
159__class__ attribute.'' If so, it is assumed that the __class__
160attribute refers to a class.
161
162<P>Let's repeat our simple example from above:
163
164<PRE>
165class C(B):
166 a = 1
167 b = 2
168</PRE>
169
170Assuming B has a __class__ attribute, this translates into:
171
172<PRE>
173C = B.__class__('C', (B,), {'a': 1, 'b': 2})
174</PRE>
175
176This is exactly the same as before except that instead of type(B),
177B.__class__ is invoked. If you have read <A HREF=
178"http://grail.cnri.reston.va.us/cgi-bin/faqw.py?req=show&file=faq06.022.htp"
179>FAQ question 6.22</A> you will understand that while there is a big
180technical difference between type(B) and B.__class__, they play the
181same role at different abstraction levels. And perhaps at some point
182in the future they will really be the same thing (at which point you
183would be able to derive subclasses from built-in types).
184
185<P>Going back to the example, the class B.__class__ is instantiated,
186passing its constructor the same three arguments that are passed to
187the default class constructor or to an extension's metaprogramming
188code: <i>name</i>, <i>bases</i>, and <i>namespace</i>.
189
190<P>It is easy to be confused by what exactly happens when using a
191metaclass, because we lose the absolute distinction between classes
192and instances: a class is an instance of a metaclass (a
193``metainstance''), but technically (i.e. in the eyes of the python
194runtime system), the metaclass is just a class, and the metainstance
195is just an instance. At the end of the class statement, the metaclass
196whose metainstance is used as a base class is instantiated, yielding a
197second metainstance (of the same metaclass). This metainstance is
198then used as a (normal, non-meta) class; instantiation of the class
199means calling the metainstance, and this will return a real instance.
200And what class is that an instance of? Conceptually, it is of course
201an instance of our metainstance; but in most cases the Python runtime
202system will see it as an instance of a a helper class used by the
203metaclass to implement its (non-meta) instances...
204
205<P>Hopefully an example will make things clearer. Let's presume we
206have a metaclass MetaClass1. It's helper class (for non-meta
207instances) is callled HelperClass1. We now (manually) instantiate
208MetaClass1 once to get an empty special base class:
209
210<PRE>
211BaseClass1 = MetaClass1("BaseClass1", (), {})
212</PRE>
213
214We can now use BaseClass1 as a base class in a class statement:
215
216<PRE>
217class MySpecialClass(BaseClass1):
218 i = 1
219 def f(s): pass
220</PRE>
221
222At this point, MySpecialClass is defined; it is a metainstance of
223MetaClass1 just like BaseClass1, and in fact the expression
224``BaseClass1.__class__ == MySpecialClass.__class__ == MetaClass1''
225yields true.
226
227<P>We are now ready to create instances of MySpecialClass. Let's
228assume that no constructor arguments are required:
229
230<PRE>
231x = MySpecialClass()
232y = Myspecialclass()
233print x.__class__, y.__class__
234</PRE>
235
236The print statement shows that x and y are instances of HelperClass1.
237How did this happen? MySpecialClass is an instance of MetaClass1
238(``meta'' is irrelevant here); when an instance is called, its
239__call__ method is invoked, and presumably the __call__ method defined
240by MetaClass1 returns an instance of HelperClass1.
241
242<P>Now let's see how we could use metaprogramming -- what can we do
243with metaclasses that we can't easily do without them? Here's one
244idea: a metaclass could automatically insert trace calls for all
245method calls. Let's first develop a simplified example, without
246support for inheritance or other ``advanced'' Python features (we'll
247add those later).
248
249<PRE>
250import types
251
252class Tracing:
253 def __init__(self, name, bases, namespace):
254 """Create a new class."""
255 self.__name__ = name
256 self.__bases__ = bases
257 self.__namespace__ = namespace
258 def __call__(self):
259 """Create a new instance."""
260 return Instance(self)
261
262class Instance:
263 def __init__(self, klass):
264 self.__klass__ = klass
265 def __getattr__(self, name):
266 try:
267 value = self.__klass__.__namespace__[name]
268 except KeyError:
269 raise AttributeError, name
270 if type(value) is not types.FuncType:
271 return value
272 return BoundMethod(value, self)
273
274class BoundMethod:
275 def __init__(self, function, instance):
276 self.function = function
277 self.instance = instance
278 def __call__(self, *args):
279 print "calling", self.function, "for", instance, "with", args
280 return apply(self.function, (self.instance,) + args)
281<HR>
282
283Confused already?
284
285
286<P>XXX More text is needed here. For now, have a look at some very
287preliminary examples that I coded up to teach myself how to use this
288feature:
289
290
291
292<H2>Real-life Examples</H2>
293
294<DL>
295
296<DT><A HREF="Enum.py">Enum.py</A>
297
298<DD>This (ab)uses the class syntax as an elegant way to define
299enumerated types. The resulting classes are never instantiated --
300rather, their class attributes are the enumerated values. For
301example:
302
303<PRE>
304class Color(Enum):
305 red = 1
306 green = 2
307 blue = 3
308print Color.red
309</PRE>
310
311will print the string ``Color.red'', while ``Color.red==1'' is true,
312and ``Color.red + 1'' raise a TypeError exception.
313
314<P>
315
316<DT><A HREF="Trace.py">Trace.py</A>
317
318<DD>The resulting classes work much like standard classes, but by
319setting a special class or instance attribute __trace_output__ to
320point to a file, all calls to the class's methods are traced. It was
321a bit of a struggle to get this right. This should probably redone
322using the generic metaclass below.
323
324<P>
325
326<DT><A HREF="Meta.py">Meta.py</A>
327
328<DD>A generic metaclass. This is an attempt at finding out how much
329standard class behavior can be mimicked by a metaclass. The
330preliminary answer appears to be that everything's fine as long as the
331class (or its clients) don't look at the instance's __class__
332attribute, nor at the class's __dict__ attribute. The use of
333__getattr__ internally makes the classic implementation of __getattr__
334hooks tough; we provide a similar hook _getattr_ instead.
335(__setattr__ and __delattr__ are not affected.)
336(XXX Hm. Could detect presence of __getattr__ and rename it.)
337
338<P>
339
340<DT><A HREF="Eiffel.py">Eiffel.py</A>
341
342<DD>Uses the above generic metaclass to implement Eiffel style
343pre-conditions and post-conditions.
344
345<P>
346</DL>
347
348</BODY>
349
350</HTML>