Chris Rebert <c...@rebertia.com> writes: > On Mon, Feb 15, 2010 at 10:29 AM, Leo Breebaart <l...@lspace.org> wrote: > > > I have a base class Foo with a number of derived classes FooA, > > FooB, FooC, etc. Each of these derived classes needs to read > > (upon initialisation) text from an associated template file > > FooA.tmpl, FooB.tmpl, FooC.tmpl, etc. > > [...] > > But, since this information is the same for every instance of > > each derived class, I was wondering if there was a way to achieve > > the same thing outside of the __init__ function, and just have > > these assignments be done as a class attribute (i.e. so that I > > can refer to FooA.template_body, etc.) > > Metaclasses to the rescue!: > > class WithTemplateAttrs(type): > def __new__(cls, name, bases, dct): > klass =3D type.__new__(cls, name, bases, dct) > klass.template_filename =3D "%s.tmpl" % name > klass.template_body =3D read_body_from(klass.template_filename) > return klass > > class Foo(object): > __metaclass__ =3D WithTemplateAttrs > #rest of class body here > > Now just have FooA, FooB, etc. subclass Foo as before. They'll > automatically get the attributes generated.
Thanks for the feedback! I am thrilled that an actual real-life issue I'm having may be resolvable by metaclasses (which so far I've only admired from afar but never considered relevant to my day-to-day work), but unfortunately I'm still struggling to get this to work. If I add your code, what happens is that the Foo class will try to read "Foo.tmpl", which does not exist -- it is only the derived classes FooA etc, that need to execute this code, not Foo itself. And actually that makes sense -- I think my problem was not too clearly thought out to begin with. Of course it's not possible to associate a single template_body with the Foo class, it will be a different template for each derived class. So at best I need to associate your metaclass with each derived class, but at that point I might as well just read the template in the __init__() method with __class__.__name__, and use lazy evaluation / caching to avoid doing the actual file-reading work more than once. I think. -- Leo Breebaart <l...@lspace.org> -- http://mail.python.org/mailman/listinfo/python-list