Update locals()

Alex Martelli aleax at aleax.it
Sun Apr 28 02:30:29 EDT 2002


On Sunday 28 April 2002 01:30, holger krekel wrote:
	...
> speaking of it, why is it possible (read: works) to say
>
> class dictlookup(dict):
>     __getattr__ = dict.get
>
> but not
>
> class dictlookup(dict):
>     __getattr__ = dict.__getitem__
>
> am i missing something?

Types:

>>> dict.__getitem__
<slot wrapper '__getitem__' of 'dict' objects>
>>> dict.get
<method 'get' of 'dict' objects>

Not all callable types function identically in all positions (at
least not yet, probably not ever) and in particular a 'slot wrapper'
instance need not be usable in lieu of a 'method' instance.


> > why ever should the dirty, terrible hacks be allowed
>
> i would answer "for use with exec" but you already said that
> this works. You are probably going to say that "exec" is the
> next candidate for evil hacks. 

At least 'exec' (without explicit dictionaries) is an immediate signal to 
the compiler and to the human reader of the program -- it means "i, the 
author of this program, have not had time to think the problem through
carefully and come up with a decent solution, so I kludged up this fragile
and unmaintainable hack".  So the compiler knows it can turn off any
attempt at optimization, as this cannot possibly be a production program,
and the human reader knows where to look for any mysterious
misbehavior.

> That may be true but it certainly
> has its good uses and i appreciate that assigning to locals from
> within "exec" is allowed. 

Please give ONE example which, in your opinion, is best handled
with 'exec' without explicit dictionaries rather than in any other way.

For extra credit, please make sure that the advantage is worth a 
3200% slowdown:

>>> import time
>>> def woe(x):
...   return x+1
...
>>> def wie(x):
...   exec ''
...   return x+1
...
>>> def timeit(f):
...   a=time.clock()
...   for i in range(10000): f(i)
...   b=time.clock()
...   return b-a
...
>>> timeit(woe)
0.009999999999999995
>>> timeit(wie)
0.33000000000000002
>>>

The exec statement in wie tells the compiler that it has to turn
all optimization off.

I'm reasonably confident that, whatever use example you can come
up with, I can suggest better alternatives that do not use exec without
explicit dictionaries.

> When you want to have e.g. templated
> parts of your program (see c++) this really helps. Or would
> you go as far as to say that templating is not really needed
> with python?

Speaking as a C++ expert (Brainbench MVP for C++), ever since I started 
with Python I found all coding in Python interestingly close to coding C++ 
templates.  The key similarity is signature-based polymorphism, that's 
always on in Python (until and unless one type-tests, a practice that is 
best avoided over 9 times in 10) but needs templates in C++.

On the other hand, Python's polymorphism works at runtime, so in terms of 
_performance_ C++ can run rings around Python in the most favourable (to
C++) cases.  Indeed, one uses C++ or C to code highly optimized extensions
to Python exactly to exploit this performance gain.

Neither issue is affected in the least by exec without explicit 
dictionaries -- except that performance further plummets.

Note that C++'s templates are never usable to define local variables with
arbitrary names unknown at compile-time: template parameters are
typenames or constants.  In Python you can pass type objects as arguments
(and similarly for the values, of course) and, apart from performance, get
exactly the same effect (and then some) WITHOUT using exec.


Alex





More information about the Python-list mailing list