[Python-3000] Metaclasses in Py3K
Jim Jewett
jimjjewett at gmail.com
Tue Dec 12 18:09:11 CET 2006
On 12/8/06, Guido van Rossum <guido at python.org> wrote:
> I've been thinking about this too, and I think it's reasonable to let
> the metaclass provide the dict to be used as locals.
Is this something that could be done in 2.6, so long as the metaclass
does happen to be set before the class statement?
> This is easier when the metaclass is given in the class header, ...
> I'd rather innovate a bit more and add keyword arguments to the class header,
> class C(B1, B2, metaclass=Foo):
> ...
Something about that seems to be begging for either confusion (when
can/must I use a keyword?) or a mess (which keywords can I use? What
code handles them?)
Would this be a reasonable use of a with- block?
Better yet, could it be done with a class decorator?
@meta(Foo)
class C(B1, B2): ...
Typically, the decorator wouldn't be *called* until too late, but the
decorator would be *created* (specialized to Foo) in time. Could it
open a with-context that resets the default metaclass for the duration
of the class statement?
(Strangely enough, when I tried this out, a with- block that set the
module-global __metaclass__ seemed to work for classic classes but not
for new-style classes. I didn't investigate beyond that. Code below
the .sig for those who care.)
-jJ
"""with-statement for metaclass"""
from __future__ import with_statement
from contextlib import contextmanager
@contextmanager
def meta(mcls):
"""Sets mcls as the default metaclass for the duration of the with-block"""
global __metaclass__
try:
oldmeta = __metaclass__
except NameError:
oldmeta = None
__metaclass__ = mcls
yield
if oldmeta is None:
del __metaclass__
else:
__metaclass__ = oldmeta
########## testing ############
class ChattyType(type):
def __new__(cls, name, bases, dct):
print "Allocating memory for class", name
return type.__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
print "Init'ing (configuring) class", name
super(ChattyType, cls).__init__(name, bases, dct)
class N1(object):
pass
class O1:
pass
with meta(ChattyType):
class N2(object):
pass
class O2:
pass
class Nesting1(object):
class Nesting2(N2):
class NestingO(O2):
class NestingOb:
class NestingNdeep(object):
pass
class N3(object):
pass
class O3:
pass
More information about the Python-3000
mailing list