By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,400 Members | 1,269 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,400 IT Pros & Developers. It's quick & easy.

circular dependency between class and its metaclass

P: n/a
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
Jul 18 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
Stefan Seefeld <se*****@sympatico.ca> wrote in message news:<ma**************************************@pyt hon.org>...
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


If "i" is a subclass of Class, then it is an instance of Type: this means
that you can write

class Type(type):
def __init__(cls, name, bases, dict):
hierarchy = [i for i in bases if isinstance(i, Type)]
# I like list comprehension...

class Class(object):
__metaclass__ = Type

Is this nice enough for you?

Michele Simionato
Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.