@@ -23,7 +23,7 @@ <H4>XXX This is very much a work in progress.</H4>
2323Fulton has used it in his < A
2424HREF ="http://www.digicool.com/papers/ExtensionClass.html "> Extension
2525Classes</ A > package. (It has also been referred to as the ``Don
26- Beaudry < i > hack</ i > , but that's a misnomer. There's nothing hackish
26+ Beaudry < i > hack</ i > ,'' but that's a misnomer. There's nothing hackish
2727about it -- in fact, it is rather elegant and deep, even though
2828there's something dark to it.)
2929
@@ -182,6 +182,11 @@ <H2>Writing Metaclasses in Python</H2>
182182in the future they will really be the same thing (at which point you
183183would be able to derive subclasses from built-in types).
184184
185+ < P > At this point it may be worth mentioning that C.__class__ is the
186+ same object as B.__class__, i.e., C's metaclass is the same as B's
187+ metaclass. In other words, subclassing an existing class creates a
188+ new (meta)inststance of the base class's metaclass.
189+
185190< P > Going back to the example, the class B.__class__ is instantiated,
186191passing its constructor the same three arguments that are passed to
187192the default class constructor or to an extension's metaprogramming
@@ -229,7 +234,7 @@ <H2>Writing Metaclasses in Python</H2>
229234
230235< PRE >
231236x = MySpecialClass()
232- y = Myspecialclass ()
237+ y = MySpecialClass ()
233238print x.__class__, y.__class__
234239</ PRE >
235240
@@ -468,7 +473,7 @@ <H1>Real-life Examples</H1>
468473< P >
469474
470475< DT > < A HREF ="Eiffel.py "> Eiffel.py</ A >
471- ppp
476+
472477< DD > Uses the above generic metaclass to implement Eiffel style
473478pre-conditions and post-conditions.
474479
@@ -481,6 +486,12 @@ <H1>Real-life Examples</H1>
481486
482487< P >
483488
489+ < DT > < A HREF ="Simple.py "> Simple.py</ A >
490+
491+ < DD > The example module used above.
492+
493+ < P >
494+
484495</ DL >
485496
486497< P > A pattern seems to be emerging: almost all these uses of
@@ -493,6 +504,82 @@ <H1>Real-life Examples</H1>
493504as well. This needs more research. Perhaps a metaclass could be
494505provided that allows stackable wrappers...
495506
507+ < HR >
508+
509+ < H2 > Things You Could Do With Metaclasses</ H2 >
510+
511+ < P > There are lots of things you could do with metaclasses. Most of
512+ these can also be done with creative use of __getattr__, but
513+ metaclasses make it easier to modify the attribute lookup behavior of
514+ classes. Here's a partial list.
515+
516+ < P >
517+
518+ < UL >
519+
520+ < LI > Enforce different inheritance semantics, e.g. automatically call
521+ base class methods when a derived class overrides< P >
522+
523+ < LI > Implement class methods (e.g. if the first argument is not named
524+ 'self')< P >
525+
526+ < LI > Implement that each instance is initialized with < b > copies</ b > of
527+ all class variables< P >
528+
529+ < LI > Implement a different way to store instance variables (e.g. in a
530+ list kept outside the the instance but indexed by the instance's id())< P >
531+
532+ < LI > Automatically wrap or trap all or certain methods
533+
534+ < UL >
535+
536+ < LI > for tracing
537+
538+ < LI > for precondition and postcondition checking
539+
540+ < LI > for synchronized methods
541+
542+ < LI > for automatic value caching
543+
544+ </ UL >
545+ < P >
546+
547+ < LI > When an attribute is a parameterless function, call it on
548+ reference (to mimic it being an instance variable); same on assignment< P >
549+
550+ < LI > Instrumentation: see how many times various attributes are used< P >
551+
552+ < LI > Different semantics for __setattr__ and __getattr__ (e.g. disable
553+ them when they are being used recursively)< P >
554+
555+ < LI > Abuse class syntax for other things< P >
556+
557+ < LI > Experiment with automatic type checking< P >
558+
559+ < LI > Delegation (or acquisition)< P >
560+
561+ < LI > Dynamic inheritance patterns< P >
562+
563+ < LI > Automatic caching of methods< P >
564+
565+ </ UL >
566+
567+ < P >
568+
569+ < HR >
570+
571+ < H4 > Credits</ H4 >
572+
573+ < P > Many thanks to David Ascher and Donald Beaudry for their comments
574+ on earlier draft of this paper. Also thanks to Matt Conway and Tommy
575+ Burnette for putting a seed for the idea of metaclasses in my
576+ mind, nearly three years ago, even though at the time my response was
577+ ``you can do that with __getattr__ hooks...'' :-)
578+
579+ < P >
580+
581+ < HR >
582+
496583</ BODY >
497584
498585</ HTML >
0 commit comments