how are dictionary literals handled by the interpreter?

Bruno Desthuilliers onurb at xiludom.gro
Thu Sep 14 16:21:51 EDT 2006


akameswaran at gmail.com wrote:
> Bruno Desthuilliers wrote:
>> akameswaran at gmail.com wrote:
(snip)
>>> class caseFunction(object):
>>>     def __init__(self):
>>>         self.caseDict = {'a':"retval = 'a'",
>>> 'b':"retval='b'","c":"retval='c'","d":"retval='d'",
>>>
>>> "e":"retval='e'","f":"retval='f'","g":"retval='g'","h":"retval='h'",
>>>                          "i":"retval='i'"}
>>>
>>>     def doIt(self,a):
>>>         exec(self.caseDict.get(a))
>>>         return retval
>> Err...  Why would you want to exec anything here ? Remember that
>> Python's functions are objects too:
>>
> Largely because it was immaterial to what I am asking about here, which
> is dictionary literals. 

Indeed. But it could as well have been related to not knowing about
first-class functions (I always suspect something wrong when I see and
exec or eval...)

> I was also curious about how much overhead
> exec had - even on simple statements, and it's about as bad as I would
> have guessed.  Finally - it's a little quicker to write out the exec
> dictionary than all of the functions ;)

(snip)

>> class SwitchFunc(object):
>>   def __init__(self, default, **kw):
>>     self._default = default
>>     self._switch = kw
>>
>>   # makes the object callable.
>>   def __call__(self, case, *args, **kw):
>>     func = self._switch.get(case, self._default)
>>     return func(*args, **kw)
>>
>> switch = SwitchFunc(defaultFunc, a=funcA, b=funcB, c=funcC)
>>
>> for case in "abcX":
>>   print switch(case, "foo", q=42)
>>
> Now I'm not sure what the value of "semi" abstraction is here.

Nor am I - I never came to write such a code in now 6+ years of Python
programming (and believe me, I sometimes write weird and hairy code !-).

>  If we
> are going to make the class semi generic, might as well have it use
> exec, then the function determined by the switch statement could be
> dynamically changed at runtime

Actually, there are few things that can't be dynamically changed at
runtime in Python !-p

> (and run like a pig).

>  Otherwise, we need
> to have those functions implemented so what do we gain? 

If you find a way to run code that's not been written one way or
another, *please* share with us !-)

> I was also
> going to say, why not make the functions instance methods, but --
> surprise surprise - when I timed it out, the lookup was ever so
> slightly slower for the instance methods. 

Hardly surprising - method lookup and invocation is a somewhat involved
process (read about the descriptor protocol and __getattribute__'s
implementation for new style classes...).

> I had to do about 100,000
> loops of it for the speed difference to be definitive, but oddly enough
> lookup to the module function was faster than looking up an instance
> method.

Yes. The faster lookup is probably in the local namespace, but then it
would requires a rewrite of the switcher for each and every use case -
in which case it's simpler to rewrite the whole mechanism where needed...

As as side note, the absence of a switch statement in Python usually
leads me to think of a better (IMHO at least) design - but I'm not
really a speed-freak, so YMMV...

-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list