Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Question about locals()

Reply
Thread Tools

Re: Question about locals()

 
 
John O'Hagan
Guest
Posts: n/a
 
      05-19-2009
On Tue, 19 May 2009, Gökhan SEVER wrote:
> Hello,
>
> Could you please explain why locals() allow me to create variables that are
> not legal in Python syntax. Example: locals()['1abc'] = 55. Calling of 1abc
> results with a syntax error. Shouldn't it be better to raise an error
> during the variable creation time?
>


The docs warn against modifying locals() because for one thing, the
interpreter may not know about the changes you make.

You can add any item to the locals() dictionary without causing an error, but
that doesn't necessarily mean you have created a legal object and named it.

But admittedly that doesn't actually answer your question.

Regards,

John


 
Reply With Quote
 
 
 
 
Steven D'Aprano
Guest
Posts: n/a
 
      05-19-2009
Sorry for breaking threading, the original post is not being carried by
my ISP.


On Tue, 19 May 2009, Gökhan SEVER wrote:
> Hello,
>
> Could you please explain why locals() allow me to create variables that
> are not legal in Python syntax. Example: locals()['1abc'] = 55. Calling
> of 1abc results with a syntax error. Shouldn't it be better to raise an
> error during the variable creation time?


No, because it isn't an error to use '1abc' as a dictionary key.

"locals()['1abc'] = 55" does not create a variable. It creates an object
55, a string '1abc', and uses that string as the key in a dict with 55 as
the value.

"locals()['abc'] = 55" does not create a variable either. It does exactly
the same thing as above, except that in this case 'abc' happens to be a
valid identifier.

"abc = 55" also does not create a variable. What it does is exactly the
same as the above, except that the dictionary key is forced to be a valid
identifier by the parser (or perhaps the lexer): the parser won't accept
1abc as a valid identifier, so you can't execute "1abc = 55".

(Almost... there's actually a slight complication, namely that making
changes to locals() inside a function does not work.)

Python's programming model is based on namespaces, and namespaces are
implemented as dictionaries: so-called "variables" are key/value pairs
inside a dictionary. Just because a dictionary is used as a namespace
doesn't stop it from being used as a dictionary: you can add any keys/
values which would otherwise be valid. It's still a dictionary, just like
any other dictionary.

>>> globals()[45] = None
>>> globals()

{'__builtins__': <module '__builtin__' (built-in)>, 45: None, '__name__':
'__main__', '__doc__': None}


As for *why* this is done this way, the answer is simplicity of
implementation. Dictionaries don't need to care about what counts as a
valid identifier. Only the lexer/parser needs to care.


--
Steven
 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      05-22-2009
En Tue, 19 May 2009 14:06:04 -0300, Gökhan SEVER <(E-Mail Removed)>
escribió:

> I will make double sure myself while using locals() to end up with valid
> identifiers.


I would ask myself why I'm using locals() in the first place.


--
Gabriel Genellina

 
Reply With Quote
 
David Robinow
Guest
Posts: n/a
 
      05-22-2009
On Fri, May 22, 2009 at 10:27 AM, Gökhan SEVER <(E-Mail Removed)> wrote:
....
> serialc = np.loadtxt(sys.argv[1], skiprows=skiprows).T
> for i in range(20):
> *** locals()['serialc_bin' + str(i+1)] = serialc[i+4]
>
> I don't know easier way than using locals() to construct variable-like
> identities in my program.


I don't either. I also don't know why you feel you need to construct
variable-like identities.
Why is:
serialc_bin1
better than
serialc_bin[0]
or, for that matter,
serialc[4]

???
 
Reply With Quote
 
J. Cliff Dyer
Guest
Posts: n/a
 
      05-22-2009
Top-posting corrected.

On Fri, 2009-05-22 at 10:00 -0500, Gökhan SEVER wrote:

> On Fri, May 22, 2009 at 9:43 AM, David Robinow <(E-Mail Removed)>
> wrote:
> On Fri, May 22, 2009 at 10:27 AM, Gökhan SEVER
> <(E-Mail Removed)> wrote:
> ...
> > serialc = np.loadtxt(sys.argv[1], skiprows=skiprows).T
> > for i in range(20):
> > locals()['serialc_bin' + str(i+1)] = serialc[i+4]
> >
> > I don't know easier way than using locals() to construct

> variable-like
> > identities in my program.

>
>
> I don't either. I also don't know why you feel you need to
> construct
> variable-like identities.
> Why is:
> serialc_bin1
> better than
> serialc_bin[0]
> or, for that matter,
> serialc[4]
>
> ???
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>


> Because in this case serialc is an numpy array. Since loadtxt returns
> a numpy-array. Furthermore
>
> locals()['serialc_bin' + str(i+1)] creates a dictionary key (that's
> what I use the term "variable-like") serialc_bin1, serialc_bin2, ...
> not serialc_bin[0] with indexes.
>
>
> Gökhan
>
>


I'm not sure why dictionary keys are better than indexes in your
example, especially as they're being created by coercing integers to
strings. However, that's your business. But why not just create your
own dictionary. Then you can pass the results around easily as a group
or one at a time, and you don't have to mess in locals() (which isn't
supposed to be messed in). It also gives you more flexibility as to how
you name your entries:

d = {}

You can use the same indexes you're using now:

d['serialc_bin' + str(i+1)] = serialc[i+4]

or you can keep the integerness of i by using tuples as keys (thus
preserving sort order across your keys):

d[('serialc_bin', i+1)] = serialc[i+4]

or you can use the integer as a key by itself (yes! It looks like
you're accessing a list, but it's actually a dict with integer keys):

d[i+1] = serialc[i+4]

Or you can use a dict with a more descriptive name and the last above
solution gains the readability of your initial solution:

serialc_bin = {}
serialc_bin[i+1] = serialc[i+4]

Finally, if there's more you want to do with these numbers, you can
create a class to hold them. Then as you need to, you can add methods
to it to implement the behavior you're looking for.

class MyCollection(object):
"""Untested code"""

def __init__(self):
self._store = {}

def __getitem__(self, item):
return self._store[item]

def __setitem__(self, item, value):
self._store[item] = value

def __delitem__(self, item):
del(self._store[item])

def sum(self):
total = 0
for value in self._store.values():
total += value
return value

serialc_bin = MyCollection()
for i, value in enumerate(serialc):
serialc_bin[i+1] = value
print serialc_bin.sum()

Any one of these seems like a better idea to me than trying to pollute
your local namespace with an unknown number of variables. You have a
collection of objects. It makes sense to store them in one of python's
collection types, or create an object of your own to store them.

Cheers,
Cliff


 
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
question row filter (more of sql query question) =?Utf-8?B?YW5kcmV3MDA3?= ASP .Net 2 10-06-2005 01:07 PM
Quick Question - Newby Question =?Utf-8?B?UnlhbiBTbWl0aA==?= ASP .Net 4 02-16-2005 11:59 AM
Question on Transcender Question :-) eddiec MCSE 6 05-20-2004 06:59 AM
Question re: features of the 831 router (also a 924 question) Wayne Cisco 0 03-02-2004 07:57 PM
Syntax Question - Novice Question sean ASP .Net 1 10-20-2003 12:18 PM



Advertisments