Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > setting variables in the local namespace

Reply
Thread Tools

setting variables in the local namespace

 
 
Chris Withers
Guest
Posts: n/a
 
      10-13-2009
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...

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?

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

cheers,

Chris

--
Simplistix - Content Management, Batch Processing & Python Consulting
- http://www.simplistix.co.uk
 
Reply With Quote
 
 
 
 
Mick Krippendorf
Guest
Posts: n/a
 
      10-13-2009
Hello.

Chris Withers schrieb:
> 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 don't really understand what you mean by "*exactly* the same".
request.GET.get('sort') ?
or
request.session[fname] = locals()['sort']
maybe? or sth else?

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


From the "request.session" stuff I conclude you're writing a webapp.
Compared to all the other time consuming things involved, I think,
another function call is negligible.

> What I'd be looking for is something like:
>
> locals()[name]=value


That will probably do what you want, and if that is a good idea depends
not on the pythonicity of it per se, but on the context in which you use
it, which I, as mentioned earlier, don't quite understand.

> - what is so wrong with wanting to set a variable in the local namespace
> based on a name stored in a variable?


What's your use case, I ask?

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


Yes, and, uh, yes. "locals()['foo'] = bar" works in that it does the
same thing as "foo = bar". So why don't you write that instead?

Mick.
 
Reply With Quote
 
 
 
 
Carl Banks
Guest
Posts: n/a
 
      10-13-2009
On Oct 13, 9:05*am, Chris Withers <(E-Mail Removed)> 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
 
Reply With Quote
 
Mel
Guest
Posts: n/a
 
      10-13-2009
Chris Withers wrote:

> - what is so wrong with wanting to set a variable in the local namespace
> based on a name stored in a variable?


What's wrong is that no other statement using the local name space can know
what that name might be. It's a documented fact that changing the locals()
dictionary doesn't feed back to the users of the namespace:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():

.... foo=0
.... globals()['foo'] = 'bar'
.... return foo
....
>>> f()

0

For the reasons Gabriel gave outside the thread.

You can actually assign into a local namespace using exec:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def g(s):

.... exec (s)
.... return a
....
>>> g('a=4')

4

But look at the dependency you'll create between the function's code and the
incoming data stream:

>>> g('b=5')

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in g
NameError: name 'a' is not defined


Once you start naming local variables at run-time, you pretty much commit to
writing the entire function at run-time. Better to use a dictionary.

Mel.

 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      10-13-2009
On Oct 13, 9:39*am, Mick Krippendorf <(E-Mail Removed)> wrote:
> Yes, and, uh, yes. "locals()['foo'] = bar" works in that it does the
> same thing as "foo = bar". So why don't you write that instead?


Lemme guess.

You tried this at the interactive prompt and concluded it worked in
general, right?

Even though when we speak of local variables, we usually are referring
to local variables inside a function, you didn't actually test whether
locals() works in a function, did you?

Because if you had you would have seen it doesn't work.


One of these days we're going to have a thread like this where no one
makes this mistake. Don't know when, but one day it will happen.


Carl Banks
 
Reply With Quote
 
Dave Angel
Guest
Posts: n/a
 
      10-13-2009
Mick Krippendorf wrote:
> <snip>
>
> Yes, and, uh, yes. "locals()['foo'] = bar" works in that it does the
> same thing as "foo = bar". So why don't you write that instead?
>
> Mick.
>
>

I wouldn't expect it to do the same thing at all, and it doesn't, at
least not in Python 2.6.2. It may store the "bar" somewhere, but not in
anything resembling a local variable.


bar = 42

def mytestfunc():
stuff = 9
locals()['stuff'] = bar
print locals()['stuff']
print stuff

mytestfunc()

prints 9, twice. No sign of the 42 value.


DaveA

 
Reply With Quote
 
Peter Pearson
Guest
Posts: n/a
 
      10-13-2009
On Tue, 13 Oct 2009 17:05:03 +0100, Chris Withers wrote:
[snip]
> - what is so wrong with wanting to set a variable in the local namespace
> based on a name stored in a variable?


I'm not sure it's "so wrong" that one should never, ever do
it, but it *does* blur the boundary between the program and
the data on which the program operates. Also, variable
names are customarily for the convenience of programmers, and
have often (e.g., compiled languages) disappeared by
run-time; so run-time references to variable names seem to
puncture the "what's for programmers" / "what's for the hardware"
distinction.

It strikes me much as the question, "What's so wrong with having
a soda straw going from the driver's seat to the gas tank?" Curious
question. Go ahead! Odd that it should seem desirable, though.
I hope the smart guys on this group can do a more precise job of
expressing this.

--
To email me, substitute nowhere->spamcop, invalid->net.
 
Reply With Quote
 
Mick Krippendorf
Guest
Posts: n/a
 
      10-13-2009
Carl Banks schrieb:
> Lemme guess.
>
> You tried this at the interactive prompt and concluded it worked in
> general, right?


Yes. Thank you for enlighten me.

> One of these days we're going to have a thread like this where no one
> makes this mistake. Don't know when, but one day it will happen.


But at least it will not be my mistake anymore.

Mick.
 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      10-13-2009
On Oct 13, 12:23*pm, Mick Krippendorf <(E-Mail Removed)> wrote:
> Carl Banks schrieb:
>
> > Lemme guess.

>
> > You tried this at the interactive prompt and concluded it worked in
> > general, right?

>
> Yes. Thank you for enlighten me.
>
> > One of these days we're going to have a thread like this where no one
> > makes this mistake. *Don't know when, but one day it will happen.

>
> But at least it will not be my mistake anymore.


One by one, baby. It just amazes me so many people don't think to
check inside a function, especially when we normally think of local
variables as being local to a function. If I wasn't familiar with
locals(), it probably wouldn't even occur to me to try using locals()
at the top level. I'd expect it to throw an exception like "No locals
at global level".


Carl Banks
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Setting local variables for 'erb' command-line tool Brian Candler Ruby 2 10-14-2010 04:26 PM
setting local variables in a binding Martin DeMello Ruby 13 10-14-2010 07:54 AM
setting local variables via eval ara howard Ruby 15 03-12-2008 12:02 PM
Can local function access local variables in main program? Sullivan WxPyQtKinter Python 10 11-08-2007 02:51 PM
different handling of local variables and instance variables when undefined Tammo Tjarks Ruby 2 09-13-2007 06:29 PM



Advertisments