Reference class in class creation

Carl Banks pavlovevidence at
Tue Nov 21 14:42:58 CET 2006

Gregor Horvath wrote:
> Diez B. Roggisch schrieb:
> > Anything wrong with:
> >
> > class Foo(object):
> >    pass
> >
> > Foo.a = Foo
> >
> > ?
> Thanks.
> The problem with this is that there is also metaclass hacking involved
> which relies on "a" 's creation in the class body. In your suggestion
> "a" is not present when __new__ of the metaclass is called.

The metaclass's __new__ returns the class object.  This is the first
time the object is available; it's impossible to access before that,
but you can get at it before __new__ exits.  Most metaclass __new__
functions look like this:

def __new__(metatype,name,bases,clsdict):
    # do some weird stuff here
    return type.__new__(metatype,name,bases,clsdict)

You could change it to look like this instead:

def __new__(metatype,name,bases,clsdict):
    # do some weird stuff here
    cls = type.__new__(metatype,name,bases,clsdict)
    cls.a = SomeContainer(cls)
    return cls

Or, if you can't change the metaclass, you can subclass it and override
__new__ to get at cls before __new__ exits:

def __new__(metatype,name,bases,dict):
    cls = GivenMetaclass.__new__(metatype,name,bases,dict)
    cls.a = SomeContainer(cls)
    return cls

If the "metaclass hacking" you describe is setting __metaclass__ to a
function (i.e., not metaclass hacking), then same thing applies, just
modify or wrap the function to get at the class object and do what you
need to do.

Carl Banks

More information about the Python-list mailing list