acting on items passed to a method via a dictiomary

Michael Loritsch loritsch at gmail.com
Sat Oct 16 20:40:36 CEST 2004


Jeremy Bowers <jerf at jerf.org> wrote in message news:<pan.2004.10.15.14.48.29.705882 at jerf.org>...
> On Fri, 15 Oct 2004 11:56:12 -0500, Donnal Walter wrote:
> 
> > The following method is defined in one of my classes:
> > 
> >      def setup(self, items={}):
> >          """perform setup based on a dictionary of items"""
> >          if 'something' in items:
> >              value = items['something']
> >              # now do something with value
> ...
> 
> It mostly depends on the contents of the "do something with value" that
> you have peppered throughout. I would pull out the various "do somethings"
> into methods, but other then that, if you need the full flexibility of a
> dict that can contain anything and you need to do things with arbitrary
> combinations, there is little else to do.
> 
> After pulling things out into methods, I'd actually shift the "if"
> statement into the method and do something like the following:
> 
> def setup(self, items = None):
>     if items is None:
>         items = {}
> 
>     self.items = items
> 
>     for method in ('something', 'another', 'spam', 'eggs'):
>         getattr(self, method)()
> 
> which will make it more flexible in the long term.
> 
> A few other things leap to mind (might want to separate the self.item
> setting from the loop, so children can override the loop without messing
> up items in calls to the super class; if you don't know what I mean
> because I'm being somewhat vague here, don't worry :-) ), but that's about
> all you can do without getting silly.

I agree with Jeremy here that everything depends on what "do something
with value" means.

After looking over this thread though, it appears to me that having
the 'setup()' method perform a dispatch operation using a dictionary
defined at class scope would be an easy, and extensible choice.

This way, one would not have to override the 'setup' method in derived
classes, rather one would only have to replace the class level
dispatch map, which in the examples below is named 'setupMap'.

Consider the following code, which would take a list or tuple to the
setup function.

class ListSetup:    

    def setup(self, items = None):
        if items is None:
            items = ()
        #Note, here a list is being used instead of a dictionary
        for item in items:
            if self.setupMap.has_key(item): #Ignore extra items
                self.setupMap[item](self)

    def setupfunction1(self):
        print "Called ListSetup.setupfunction1"

    def setupfunction2(self):
        print "Called ListSetup.setupfunction2"

    #This is the key to the whole thing -> a dictionary used for
    #dispatching the correct calls
    setupMap = {'something':setupfunction1, 'another':setupfunction2}


The key is in the class scope dictionary 'setupMap'.  If a key is
provided in the setup call, each of the appropropiate member functions
will be called.

On the other hand, if the 'values' stored in the dictionary passed in
are also important, we can incorporate that into our solution, by
passing them to our setupfunctionX methods as arguments.

Here is a similar solution, using an items dictionary:

class DictSetup:

    def setup(self, items = None):
        if items is None:
            items = {}
        #Note, here we are expecting a dictionary
        for key in items.keys():
            if self.setupMap.has_key(key): #Ignore extra items
                self.setupMap[key](self, items[key])
                
    def setupfunction1(self, value):
        print "Called DictSetup.setupfunction1 with value", value

    def setupfunction2(self, value):
        print "Called DictSetup.setupfunction2 with value", value

    #Again, this is the key to the whole thing -> a dictionary used
    #for dispatching the correct calls
    setupMap = {'something':setupfunction1, 'another':setupfunction2}

I hope this helps!

Michael Loritsch



More information about the Python-list mailing list