setting variables in the local namespace

Carl Banks pavlovevidence at gmail.com
Tue Oct 13 13:45:35 EDT 2009


On Oct 13, 9:05 am, Chris Withers <ch... at simplistix.co.uk> wrote:
> Hi All,
>
> Say I have a piece of code like this:
>
>          mname = model.__name__
>          fname = mname+'_order'
>          value = request.GET.get('order')
>          if value:
>              request.session[fname]=value
>          else:
>              value = request.session.get(
>                  fname,
>                  model.default_name
>                  )
>
> Now, if I want to do *exactly* the same thing with a variable named
> 'sort', I have to copy and paste the above code or do something hacky
> like have a dict called "vars" and manipulate that, or factor the above
> into a function and take the hit on the extra function call...

Just a bit of perspective:

Once you are at the point of worrying about taking a hit on an extra
function call, a lot of the other things that are normally bad ideas
(like cutting and pasting a lot of code) aren't considered "bad"
anymore.  At least, not if you have good reason to worry about the
overhead of a function call.

The right way to this kind of thing, almost always, is to factor this
code into a function.


> What I'd be looking for is something like:
>
> locals()[name]=value
>
> ...or, say:
>
> setattr(<somethingspecial>,name,value)
>
> Now, I got horribly flamed for daring to be so heretical as to suggest
> this might be a desirable thing in #python, so I thought I'd ask here
> before trying to take this to python-dev or writing a PEP:
>
> - what is so wrong with wanting to set a variable in the local namespace
> based on a name stored in a variable?

My opinion: It's not necessarily a bad thing to do per se, but
whenever people think they want to do this, very often they are
approaching the problem the wrong way, especially when done with
locals.  (There are more valid reasons to do it a global level.)

One thing I've noticed is that often people only really need the
convenient local names for testing.  Example: I once set up an object
that had dynamically-assigned attributes that it read from a file.
(So you'd write "x = load_values(filename)", and it would return an
object with attributes determined from the data in the file.)  I did
it that way because I got irritated typing x["attr"] all the time, and
thought it'd be better to type x.attr.  But, when I got around to
actually using x, I found that I was always accessing the attributes
dynamically with getattr and setattr.  Whoops, wasn't that useful
after all.

There are some cases when dynamically settable locals really might be
helpful.  I'm not saying it's heretical to want it.  But on the whole
I'd rather not see it allowed.  I'd expect it to be overused, and when
it is used readability can take a severe hit.


> - have I missed something that lets me do this already?

No.

However, one thing that might work in your case would be to then pass
a dictionary as keyword arguments into a function that defines the
locals you need.

u['value'] = 1
u['sort'] = 2
u['key'] = 3

def something(value,sort,key):
    return value + sort + key  # look they're locals now

something(**u)


Carl Banks



More information about the Python-list mailing list