updating local()

El Pitonero pitonero at gmail.com
Thu Oct 6 10:44:03 EDT 2005


Flavio wrote:
> I wish all my problems involved just a couple of variables, but
> unfortunately the real interesting problems tend to be complex...
>
> def fun(**kw):
>     a = 100
>     for k,v in kw.items():
>         exec('%s = %s'%(k,v))
>     print locals()
>
>
> >>> fun(**{'a':1,'b':2})
> {'a': 1, 'k': 'b', 'b': 2, 'kw': {'a': 1, 'b': 2}, 'v': 2}
>
> any better Ideas?

Actually, your solution is not bad. Some potential problems are: (1)
unintentional name collisions with other variables, including
globals/builtins, (2) it's easy to unpack variables into locals(), but
not easy to pack them back, since locals() are often contaminated with
extra auxiliary variables.

Your problem happens often in the field of math formulas/equations.

I remember similar problem happens in C++, too. When one has a function
with a long list of parameters, in C++ one may find oneself updating
the funtion header/prototype all the time, which is very tiresome and
error-prone.

When you have complicated list of arguments to pass, it's better to put
them into a structure/object. This way, the function header/prototype
will remain the same, and you only need to change the declaration of
the object.

The parameter object(s) could be called:

- request and response, if input and output are separated
- param
- workspace, session, etc.

so, your function call would look like

class Param: pass
...
def f(p):
    result = p.x + p.y
    return result
...
p=Param()
p.x = 3
p.y = 4
result = f(p)

Now, you may not like the extra dots in the line:

result = p.x + p.y

My experience is: it's not that bad to have names with extra dots. I
know it's annoying, but not a total disaster. Plus, once you start to
use OOP, it makes your code more organized. It has its benefits. For
instance, very often your models/formulas have several versions. Using
OOP's class hierarchy inheritance mechanism allows you to try out
different versions or different ideas much more easily, and you can
roll back the changes more easily, too (instead of commenting out code
lines all over places.) If you do decide to go the route of OOP, the
lines:

p.x = 3
p.y = 4
p.z = 5

can be replaced by something like:

calculation_engine.set(x=3, y=4)
calculation_engine.set(z=5)

----------------------

The longer answer is: if you need complex formula evaluations, Python
is probably not the language to use. For speed and memory usage issues,
C++ is probably what you need. You can hookup your C++ program to
Python in various ways, but packing/unpacking variables seems
unavoidable. And even in C++ (where object attributes don't have the
dots inside the object's own methods), I still often end up using a lot
of dotted names for attributes from other objects.

If the problem is complex, then it's complex. I know you have your
equations, but you have to decide for yourself: is it better to do all
the packing/unpacking, or is it better to change your equations to use
the dotted names? There is no right or wrong answer, it all depends on
your particular situation.




More information about the Python-list mailing list