Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #29449 > unrolled thread

User defined lexical scoping... can I do this?

Started byporkfried <weissman.mark@gmail.com>
First post2012-09-18 13:10 -0700
Last post2012-09-19 00:47 +0100
Articles 7 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  User defined lexical scoping... can I do this? porkfried <weissman.mark@gmail.com> - 2012-09-18 13:10 -0700
    Re: User defined lexical scoping... can I do this? Thomas Jollans <t@jollybox.de> - 2012-09-18 22:31 +0200
    Re: User defined lexical scoping... can I do this? weissman.mark@gmail.com - 2012-09-18 13:50 -0700
      Re: User defined lexical scoping... can I do this? Thomas Jollans <t@jollybox.de> - 2012-09-18 23:51 +0200
      Re: User defined lexical scoping... can I do this? Terry Reedy <tjreedy@udel.edu> - 2012-09-18 21:38 -0400
        Re: User defined lexical scoping... can I do this? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-09-19 04:03 +0000
    Re: User defined lexical scoping... can I do this? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-09-19 00:47 +0100

#29449 — User defined lexical scoping... can I do this?

Fromporkfried <weissman.mark@gmail.com>
Date2012-09-18 13:10 -0700
SubjectUser defined lexical scoping... can I do this?
Message-ID<d9aec95e-aedb-442d-ab6d-320f43f61b93@googlegroups.com>
I want to define a 'with' command that makes entries
in dictionary available within the local scope, and
stores new local variables into that dictionary.  The
original scope should be restored on exit, and called
functions should not see anything special.  Can I do this?

my_dict = dict(a=1, b=2)
with MyScope(my_dict):
    print "A", a, "B", b
    x = 3
print my_dict["x"]
print x # FAIL, unbound

[toc] | [next] | [standalone]


#29451

FromThomas Jollans <t@jollybox.de>
Date2012-09-18 22:31 +0200
Message-ID<mailman.891.1348000902.27098.python-list@python.org>
In reply to#29449
On 09/18/2012 10:10 PM, porkfried wrote:
> I want to define a 'with' command that makes entries
> in dictionary available within the local scope, and
> stores new local variables into that dictionary.  The
> original scope should be restored on exit, and called
> functions should not see anything special.  Can I do this?

No.*

It is not possible to set locals by ways other than an assignment**, and
it is certainly not possible to set locals in a scope other than the one
you're in**.

You should simply type out the dict's name. This is a lot clearer. If
you want to minimize typing, you can give the variable a one-character name.

Also, Python scope simply doesn't work like that. There is no block
scope, only local (=function) scope, and global scope, with a dash of
non-locals to spice things up a bit.

> 
> my_dict = dict(a=1, b=2)
> with MyScope(my_dict):
>     print "A", a, "B", b
>     x = 3
> print my_dict["x"]
> print x # FAIL, unbound
> 

*You could set global variables, and remove them on exit, but this is
ugly for a number of reasons: this could overwrite existing globals if
you're not very careful, called functions would see these globals, and
they would also be exposed to other threads.

**I believe there is actually a way to edit a caller's locals, but this
is not documented, not portable across Python implementations and
versions, and you couldn't create new locals like this, so it'd be
fairly pointless here

[toc] | [prev] | [next] | [standalone]


#29452

Fromweissman.mark@gmail.com
Date2012-09-18 13:50 -0700
Message-ID<f366b2f6-781a-4d66-9386-6be75f631ee3@googlegroups.com>
In reply to#29449
On Tuesday, September 18, 2012 4:10:32 PM UTC-4, porkfried wrote:
> I want to define a 'with' command that makes entries
> 
> in dictionary available within the local scope, and
> 
> stores new local variables into that dictionary.  The
> 
> original scope should be restored on exit, and called
> 
> functions should not see anything special.  Can I do this?
> 
> 
> 
> my_dict = dict(a=1, b=2)
> 
> with MyScope(my_dict):
> 
>     print "A", a, "B", b
> 
>     x = 3
> 
> print my_dict["x"]
> 
> print x # FAIL, unbound

Well there's wired stuff like this:

In [1]: locals()["x"] = 5

In [2]: print x
5

In [3]: 

but it didn't help me do what I wanted.

[toc] | [prev] | [next] | [standalone]


#29453

FromThomas Jollans <t@jollybox.de>
Date2012-09-18 23:51 +0200
Message-ID<mailman.892.1348005076.27098.python-list@python.org>
In reply to#29452
On 09/18/2012 10:50 PM, weissman.mark@gmail.com wrote:
> Well there's wired stuff like this:
> 
> In [1]: locals()["x"] = 5
> 
> In [2]: print x
> 5
> 

No, there isn't. Modifying the dictionary returned by locals() has no
effect.

>>> def f ():
...     locals()["x"] = 1
...     return x
...
>>> f ()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in f
NameError: global name 'x' is not defined
>>>
>>> locals()["x"] = 1
>>> x
1
>>> #this works because
... locals() is globals()
True
>>>

The exception is the case when local scope is identical to global scope.
In this case, locals() has globals() semantics.

[toc] | [prev] | [next] | [standalone]


#29460

FromTerry Reedy <tjreedy@udel.edu>
Date2012-09-18 21:38 -0400
Message-ID<mailman.898.1348018725.27098.python-list@python.org>
In reply to#29452
On 9/18/2012 5:51 PM, Thomas Jollans wrote:
> On 09/18/2012 10:50 PM, weissman.mark@gmail.com wrote:
>> Well there's wired stuff like this:
>>
>> In [1]: locals()["x"] = 5
>>
>> In [2]: print x
>> 5
>>
>
> No, there isn't. Modifying the dictionary returned by locals() has no
> effect.

Last time I tried it, it does within a class -- in cpython at least. 
That locals dict usually becomes the __dict__ of the class. But not to 
be depended on indefinitely and across implmentations.


-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#29463

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-09-19 04:03 +0000
Message-ID<505943f6$0$29890$c3e8da3$5496439d@news.astraweb.com>
In reply to#29460
On Tue, 18 Sep 2012 21:38:19 -0400, Terry Reedy wrote:

> On 9/18/2012 5:51 PM, Thomas Jollans wrote:
>> On 09/18/2012 10:50 PM, weissman.mark@gmail.com wrote:
>>> Well there's wired stuff like this:
>>>
>>> In [1]: locals()["x"] = 5
>>>
>>> In [2]: print x
>>> 5
>>>
>>>
>> No, there isn't. Modifying the dictionary returned by locals() has no
>> effect.
> 
> Last time I tried it, it does within a class -- in cpython at least.
> That locals dict usually becomes the __dict__ of the class. But not to
> be depended on indefinitely and across implmentations.

Exactly. The behaviour of modifying the dict returned by locals() is not 
defined. For example, this is what happens under Python 2.6, Jython 2.5, 
and IronPython 2.6:

steve@runes:~$ cat test.py 

a = b = 'global'
def test():
    a = None
    locals()['a'] = 'local'
    locals()['b'] = 'local'
    print a, b

test()

steve@runes:~$ python test.py 
None global
steve@runes:~$ jython test.py 
None global
steve@runes:~$ ipy test.py 
local global


Other Python implementations may do differently.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#29454

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2012-09-19 00:47 +0100
Message-ID<mailman.893.1348012052.27098.python-list@python.org>
In reply to#29449
On 18/09/2012 21:10, porkfried wrote:
> I want to define a 'with' command that makes entries
> in dictionary available within the local scope, and
> stores new local variables into that dictionary.  The
> original scope should be restored on exit, and called
> functions should not see anything special.  Can I do this?
>
> my_dict = dict(a=1, b=2)
> with MyScope(my_dict):
>      print "A", a, "B", b
>      x = 3
> print my_dict["x"]
> print x # FAIL, unbound
>

If you could state what you're trying to achieve rather than how you're 
trying to achieve it then perhaps people could give you a solution to 
your problem.

-- 
Cheers.

Mark Lawrence.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web