Modulok wrote: > List, > > I've been messing with metaclasses. I thought I understood them until I > ran into this. (See code below.) I was expecting the generated class, > 'Foo' to have an 'x' class-level attribute, as forced upon it by the > metaclass 'DracoMeta' at creation. Unfortunately, it doesn't and I don't > know why. I'm obviously missing something big. I thought a metaclass > created the class object, so this should work. (But obviously doesn't.) > > > <!-- Begin Code --> > class DracoMeta(type): > '''Metaclass that creates a serial number as a class property.''' > def __init__(self, name, bases, members): > # Force a class attribute on the class-to-be: > members['serial'] = 3 > > # Now make the class: > type.__init__(self, name, bases, members) > > class Foo(object): > __metaclass__ = DracoMeta > > print hasattr(Foo, 'serial') #<-- I was really expecting this to be > True. <!-- End Code --> > > I could add the attribute in the definition or a decorator, but the point > was learning to use (albeit abuse) metaclasses. Anyway, if anyone could > take a look I'd be grateful.
You are a little late to the show; the class, i. e. the instance of the metaclass with all its attributes has already been created by the type.__new__() method. If you move the manipulation of the members dict into a custom __new__() method you get the desired behaviour: >>> class DracoMeta(type): ... def __new__(cls, name, bases, members): ... members["serial"] = 3 ... return type.__new__(cls, name, bases, members) ... >>> class Foo: ... __metaclass__ = DracoMeta ... >>> Foo.serial 3 Alternatively you can take advantage of the fact that 'self' in the metaclass is the metaclass instance, i. e. the class, and assign directly to it: >>> class NianMeta(type): ... def __init__(self, name, bases, members): ... self.serial = 3 ... >>> class Bar: ... __metaclass__ = NianMeta ... >>> Bar.serial 3 _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor