mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
Some nits, added a whole section on what you could do with
metaclasses, and acks.
This commit is contained in:
parent
7ca65abb2f
commit
7b877a9278
1 changed files with 90 additions and 3 deletions
|
|
@ -23,7 +23,7 @@ <H4>XXX This is very much a work in progress.</H4>
|
|||
Fulton has used it in his <A
|
||||
HREF="http://www.digicool.com/papers/ExtensionClass.html">Extension
|
||||
Classes</A> package. (It has also been referred to as the ``Don
|
||||
Beaudry <i>hack</i>, but that's a misnomer. There's nothing hackish
|
||||
Beaudry <i>hack</i>,'' but that's a misnomer. There's nothing hackish
|
||||
about it -- in fact, it is rather elegant and deep, even though
|
||||
there's something dark to it.)
|
||||
|
||||
|
|
@ -182,6 +182,11 @@ <H2>Writing Metaclasses in Python</H2>
|
|||
in the future they will really be the same thing (at which point you
|
||||
would be able to derive subclasses from built-in types).
|
||||
|
||||
<P>At this point it may be worth mentioning that C.__class__ is the
|
||||
same object as B.__class__, i.e., C's metaclass is the same as B's
|
||||
metaclass. In other words, subclassing an existing class creates a
|
||||
new (meta)inststance of the base class's metaclass.
|
||||
|
||||
<P>Going back to the example, the class B.__class__ is instantiated,
|
||||
passing its constructor the same three arguments that are passed to
|
||||
the default class constructor or to an extension's metaprogramming
|
||||
|
|
@ -229,7 +234,7 @@ <H2>Writing Metaclasses in Python</H2>
|
|||
|
||||
<PRE>
|
||||
x = MySpecialClass()
|
||||
y = Myspecialclass()
|
||||
y = MySpecialClass()
|
||||
print x.__class__, y.__class__
|
||||
</PRE>
|
||||
|
||||
|
|
@ -468,7 +473,7 @@ <H1>Real-life Examples</H1>
|
|||
<P>
|
||||
|
||||
<DT><A HREF="Eiffel.py">Eiffel.py</A>
|
||||
ppp
|
||||
|
||||
<DD>Uses the above generic metaclass to implement Eiffel style
|
||||
pre-conditions and post-conditions.
|
||||
|
||||
|
|
@ -481,6 +486,12 @@ <H1>Real-life Examples</H1>
|
|||
|
||||
<P>
|
||||
|
||||
<DT><A HREF="Simple.py">Simple.py</A>
|
||||
|
||||
<DD>The example module used above.
|
||||
|
||||
<P>
|
||||
|
||||
</DL>
|
||||
|
||||
<P>A pattern seems to be emerging: almost all these uses of
|
||||
|
|
@ -493,6 +504,82 @@ <H1>Real-life Examples</H1>
|
|||
as well. This needs more research. Perhaps a metaclass could be
|
||||
provided that allows stackable wrappers...
|
||||
|
||||
<HR>
|
||||
|
||||
<H2>Things You Could Do With Metaclasses</H2>
|
||||
|
||||
<P>There are lots of things you could do with metaclasses. Most of
|
||||
these can also be done with creative use of __getattr__, but
|
||||
metaclasses make it easier to modify the attribute lookup behavior of
|
||||
classes. Here's a partial list.
|
||||
|
||||
<P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>Enforce different inheritance semantics, e.g. automatically call
|
||||
base class methods when a derived class overrides<P>
|
||||
|
||||
<LI>Implement class methods (e.g. if the first argument is not named
|
||||
'self')<P>
|
||||
|
||||
<LI>Implement that each instance is initialized with <b>copies</b> of
|
||||
all class variables<P>
|
||||
|
||||
<LI>Implement a different way to store instance variables (e.g. in a
|
||||
list kept outside the the instance but indexed by the instance's id())<P>
|
||||
|
||||
<LI>Automatically wrap or trap all or certain methods
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>for tracing
|
||||
|
||||
<LI>for precondition and postcondition checking
|
||||
|
||||
<LI>for synchronized methods
|
||||
|
||||
<LI>for automatic value caching
|
||||
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
<LI>When an attribute is a parameterless function, call it on
|
||||
reference (to mimic it being an instance variable); same on assignment<P>
|
||||
|
||||
<LI>Instrumentation: see how many times various attributes are used<P>
|
||||
|
||||
<LI>Different semantics for __setattr__ and __getattr__ (e.g. disable
|
||||
them when they are being used recursively)<P>
|
||||
|
||||
<LI>Abuse class syntax for other things<P>
|
||||
|
||||
<LI>Experiment with automatic type checking<P>
|
||||
|
||||
<LI>Delegation (or acquisition)<P>
|
||||
|
||||
<LI>Dynamic inheritance patterns<P>
|
||||
|
||||
<LI>Automatic caching of methods<P>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
|
||||
<HR>
|
||||
|
||||
<H4>Credits</H4>
|
||||
|
||||
<P>Many thanks to David Ascher and Donald Beaudry for their comments
|
||||
on earlier draft of this paper. Also thanks to Matt Conway and Tommy
|
||||
Burnette for putting a seed for the idea of metaclasses in my
|
||||
mind, nearly three years ago, even though at the time my response was
|
||||
``you can do that with __getattr__ hooks...'' :-)
|
||||
|
||||
<P>
|
||||
|
||||
<HR>
|
||||
|
||||
</BODY>
|
||||
|
||||
</HTML>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue