Differences between revisions 4 and 5
Revision 4 as of 2004-02-28 05:48:55
Size: 3835
Editor: pcp07848903pcs
Comment:
Revision 5 as of 2011-02-15 06:05:17
Size: 3835
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

Use keyword arguments for all mixins

Albatross is supposed to make it possible to easily switch between different deployment options. Currently when you change application class you must change the list of arguments that you pass to the constructor. Take for instance the ModularSessionApp class:

class ModularSessionApp(PickleSignMixin,
                        Application,
                        CachingTemplateLoaderMixin,
                        PageModuleMixin,
                        SessionServerAppMixin):
    def __init__(self, base_url, module_path, template_path, start_page, secret,
                 session_appid, session_server = 'localhost', server_port = 34343, session_age = 1800):
        Application.__init__(self, base_url)
        PickleSignMixin.__init__(self, secret)
        CachingTemplateLoaderMixin.__init__(self, template_path)
        PageModuleMixin.__init__(self, module_path, start_page)
        SessionServerAppMixin.__init__(self, session_appid, session_server, server_port, session_age)
                                                                                
    def create_context(self):
        return SessionAppContext(self)

There is a mixture of keyword and non-keyword arguments. If the interface to all of the mixins was changed to just accept **kw then the above could look like this:

class ModularSessionApp(PickleSignMixin,
                        Application,
                        CachingTemplateLoaderMixin,
                        PageModuleMixin,
                        SessionServerAppMixin):
    def __init__(self, **kw):
        Application.__init__(self, **kw)
        PickleSignMixin.__init__(self, **kw)
        CachingTemplateLoaderMixin.__init__(self, **kw)
        PageModuleMixin.__init__(self, **kw)
        SessionServerAppMixin.__init__(self, **kw)

Taking the above a little further it should be possible to do something like this:

class ModularSessionApp(KwInitBase,
                        PickleSignMixin,
                        Application,
                        CachingTemplateLoaderMixin,
                        PageModuleMixin,
                        SessionServerAppMixin):
    pass

Then in Albatross the KwInitBase class would be something like this:

class KwInitBase:
    def __init__(self, **kw):
        for klass in self.__class__.__bases__:
            if klass != KwInitBase:
                klass.__init__(self, **kw)

One big advantage to all of this is that it allows you to change application classes very easily. It would also greatly simplify the task of construcitng your own application classes from the standard mixins and your own mixins.

Comments

I think this is a good idea. It's a complicated problem, using mixins and constructors.

I was thinking of just about exactly the same thing for a GUI toolkit I was working on. I had a couple differences though, that may make it simpler for the end-user. Only the base mixin class (like your KwInitBase) has an init constructor. All mixins subclass this base mixin class, and have an OnInit method instead of init. The base mixin class calls the OnInit method for all the mixins and for the class instance (self), like so:

   1 class KwInitBase(object):
   2     def __init__(self, **kw):
   3         for klass in self.__class__.__bases__:
   4             if klass != KwInitBase:
   5                 if hasattr(klass,"OnInit"):
   6                     klass.OnInit(self, **kw)
   7         #Call self.OnInit too: (may want to call this first?)
   8         if hasattr(self,"OnInit"):
   9             self.OnInit(**kw)

I haven't really tested this yet though, and I'm not sure if using a special metaclass for the base mixin might be better.

None: KeywordArguments (last edited 2011-02-15 06:05:17 by localhost)