circular dependency between class and its metaclass

Stefan Seefeld seefeld at sympatico.ca
Sun Jan 18 15:03:48 EST 2004


hi there,

I'v run into a little problem for which I only found an ugly workaround,
so I'd like to know whether people are aware of better ways to achieve this...

I'm defining a class 'Class' for which I want to set up a __metaclass__ 'Type'
which does some work on class variables. In particular, it should apply
a function on all base classes that are themself derived from 'Class'.

My first try was:

====

class Class(object):

     class Type(type):

         def __init__(cls, name, bases, dict):

             hierarchy = list(filter(lambda i:issubclass(i, Class), bases))
             # do something with the hierarchy here

     __metaclass__ = Type

====

However, this fails because at the point where I want to create the
'hierarchy' variable 'Class' isn't known yet. (At what point is it actually
injected into the local dict ?)

Then I tried to define 'Type' after 'Class' (instead of inside it):

====

class Class(object): pass #supress details for clarity

class Type(type):
     ...

Class.__metaclass__ = Type

====

But this didn't work at all (even though I don't quite understand why).

Then I tried a workaround using an auxiliary base class:

====

class Base(object): pass #supress details for clarity

class Type(type):
     def __init__(cls, name, bases, dict):

         # now base the filter on 'Base'
         hierarchy = list(filter(lambda i:issubclass(i, Base), bases))
         # do something with the hierarchy here

class Class(Base):

     __metaclass__ = Type

     ...

====

though this is quite ugly, as 'Class' is the class that provides the stuff
the 'Type' constructor should act on, not 'Base' (so to make the filter above
work I have to do some more ugly tricks).

I'd very much appreciate if anybody could shed some light on why python
behaves the way it does in the two first cases, and whether there are
better ways to achieve what I want. Thanks a lot !

Stefan





More information about the Python-list mailing list