metaclasses, how you might actually use 'em

Jack Diederich jack at performancedrivers.com
Mon Apr 28 13:02:49 EDT 2003


On Mon, Apr 28, 2003 at 06:14:37AM -0700, Michele Simionato wrote:
> Jack Diederich <jack at performancedrivers.com> wrote in message news:<mailman.1051458882.30400.python-list at python.org>...
> 
> > <snip evangelism to metaclasses>
> 
> All your usages of metaclasses seems to me quite typical and "good"
> (to see a "bad" usage, google for my "black magic trick" ;)
> 
> Do you know that the standard 'type'
> metaclass (and therefore all metaclasses derived from it, which means
> ALL metaclasses) contains a __subclasses__ method ?
>
> I think it is quite similar in spirit to your Register, isn't it ?

Very similar for class trees with one common parent.
The Register pattern stores the info in an arbitrary location so different
class trees that have a Register metaclass can aggregate their info in a common
place.

Also, the Register pattern builds the list once when classes are defined.
Using the list afterwards is cheap.  Instead of using the list generated
by Register you could recurse down __subclassess__() each time you wanted
to iterate on the list or check for membership, but it would be more expensive.

instead of
 if (ob.__class__ in Factory.registered_classes):
  # do stuff

 if (ob.__class__ in func_to_gather_subclasses(Base)):
  # do stuff

So the Factory has to know about the Base, instead of the Base's register
method knowing about the Facotry.  The special DO_NOT_REGISTER attribute
for intermediate virtual classes also works well in the Register pattern
because we can inspect it then delete it so it isn't inherited by subclasses
and won't outlive its brief purpose (As a flag saying dont register me).

> 
> > metaclasses just allow you to tweak a class definition on the fly.  Mainly 
> > adding or removing attributes just before the class becomes 'real'. 
> 
> is correct when you redefine the __new__ method of the metaclass. However,
> in your examples, you redefine the __init__ method. This means that the
> class has been *already* created, i.e. it is 'real', and it is modified
> *after* creation. This is just nitpicking, but since you asked for pedantry...

I could never get the __new__ to do what I wanted.  I would always end up
recursively calling __new__.  Doing everything in __init__ works, so I just
kept with that.

-jackdied
http://jackdied.com/code/





More information about the Python-list mailing list