Was: Examples of metaclasses as factory functions/classes?

Michele Simionato mis6 at pitt.edu
Fri Dec 13 10:40:28 EST 2002


From: Stuart Hungerford (stuart.hungerford at anu.edu.au)
 Subject: Examples of metaclasses as factory functions/classes? 
 Newsgroups: comp.lang.python
 Date: 2002-10-16 17:11:37 PST 

>Hi all,
>
>Has anyone done any work in using Python's newish metaclasses implementation
>for creating factory functions or classes ("factory" as per the various GoF
>patterns)?
>
>Is there any advantage to handling factories this way over the usual idioms
>using keyword parameters in an __init__, or a separate function or class that
>creates instances?
>
>Also - does having __new__ influence how these creational patterns can be
>implemented compared to using __init__ alone?
>
>I-promised-timbot-no-more-design-by-contract-questions-ly-yours,
>
>Stu

It is a pity this posting dated Oct 16 had been unanswered ...

Inspired also by the recent posting by Bengt Richter 
"Another way to spell __metaclass__?" I experimented a bit with the 
concept of class factories. For this task I think the simplest way 
to go is to use a function like the following:

def makeclass(name,bases=(),dict={},*parameters):
    """According to parameters makeclass should do something nontrivial on 
    bases and/or dict, but here for sake of simplificity it does nothing."""
    print "Class %s is to be created" % name
    return type(name,bases,dict.copy())

A=makeclass('A')

print A, A.__class__

with output

  Class A is to be created
  <class '__main__.A'> <type 'type'>

By giving suitable arguments and parameters one can customize the
created classes. Notice that in this way  no A.__metaclass__ hook is defined.

One can also write something like

class B(object):
    __metaclass__=makeclass

print B, B.__class__, B.__metaclass__

with output

  <class '__main__.B'> <type 'type'> <unbound method B.makeclass>

and it works even if makeclass is not a metaclass ! The reason why it works 
is that makeclass invokes the built-in metaclass "type", I guess, but still 
there is something of magic in it. Notice that the function makeclass
becomes an unbound method of B and the contents of B.__dict__ is

  {'__dict__': <attribute '__dict__' of 'B' objects>, 
  '__weakref__': <member '__weakref__' of 'B' objects>, 
  '__module__': '__main__', '__metaclass__': <function makeclass at 0x81153ec>}

I still have to figure out how this mechanism couple with inheritance ;-)

The exploration of wonders and misteries of metaclasses continues in next
issues... 

                          stay tuned !



More information about the Python-list mailing list