how are dictionary literals handled by the interpreter?

akameswaran at gmail.com akameswaran at gmail.com
Thu Sep 14 10:30:19 EDT 2006


Bruno Desthuilliers wrote:
> akameswaran at gmail.com wrote:
> > I wrote up a quick little set of tests, I was acutally comparing ways
> > of doing "case" behavior just to get some performance information.  Now
> > two of my test cases had almost identical results which was not at all
> > what I expected.  Ultimately I realized I don't really know how
> > literals are treated within the interpreter.
> >
> > The two implementations I was looking at were:
> >
> > 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.  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 ;)

> def funcA(*args, **kw):
>   return "funcA called with %s %s" % (str(args), kw)
>
> def funcB(*args, **kw):
>   return "funcB called with %s %s" % (str(args), kw)
>
> def funcC(*args, **kw):
>   return "funcC called with %s %s" % (str(args), kw)
>
> def defaultFunc(*args, **kw):
>   return "defaultFunc called with %s %s" % (str(args), kw)
>
> 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.  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(and run like a pig).  Otherwise, we need
to have those functions implemented so what do we gain?  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.  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.

> HTH
> --
> 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