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

P

porkfried

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
 
T

Thomas Jollans

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
 
W

weissman.mark

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

Thomas Jollans

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.
.... locals()["x"] = 1
.... return x
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File said:
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.
 
M

Mark Lawrence

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

Terry Reedy

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

Steven D'Aprano

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top