acting on items passed to a method via a dictiomary

Diez B. Roggisch deetsNOSPAM at web.de
Fri Oct 15 13:21:44 EDT 2004


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
>          if 'another' in items:
>              value = items['another']
>              # do something else with value
>          if 'spam' in items:
>              value = items['spam']
>              # do yet another thing with value
>          if 'eggs' in items:
>              value = items['eggs']
>              # and so on
> 
> Any suggestion?

First of all, don't use {} as default value for items. Many have stepped
into this trap: While perfectly legal, it will be evaluated only once, when
the method setup is found the first time. So then an instance of a dict is
created. But now if subsequent calls to setup alter that dict items points
to, they all share the same dict!! This small example illustrates that
behaviour:

def foo(key, bar={}):
    bar[key] = key
    print bar

for i in xrange(3):
    foo(i)

yields:

{1:1}
{1:1, 2:2}

where you surely have expected {2:2} in the second case. So the idiom for
this commonly is this:

def foo(key, bar=None):
    if bar is None:
       bar = {} # remember: bar is a local name, bound to a value - so next
time, bar will still be none if foo is called w/o bar as parameter
    bar[key] = key

Now to your question: This works:

for k in ['something', 'another', 'spam', 'eggs']:
    if items.has_key(k):
        value = items[k]
        break


-- 
Regards,

Diez B. Roggisch



More information about the Python-list mailing list