assigning in nested functions

J

jena

Hi
I have code

# BEGIN CODE
def test():
def x():
print a
a=2 # ***

a=1
x()
print a

test()
# END CODE

This code fails (on statement print a in def x), if I omit line marked
***, it works (it prints 1\n1\n). It look like when I assign variable in
nested function, I cannot access variable in container function.
I need to assign variable in container function, is any way to do this?

Thanks a lot for your help
Jena
 
D

Diez B. Roggisch

jena said:
Hi
I have code

# BEGIN CODE
def test():
def x():
print a
a=2 # ***

a=1
x()
print a

test()
# END CODE

This code fails (on statement print a in def x), if I omit line marked
***, it works (it prints 1\n1\n). It look like when I assign variable in
nested function, I cannot access variable in container function.
I need to assign variable in container function, is any way to do this?

No. You can access them, but not rebind them. That's a crucial
difference. So, if a contains a mutable, you can alter that:

def test():
a = {"foo": "bar"}
def x():
a["foo"] = "pillepalle"
x()
print a

Or you return that value:

def test()
a = 10
def x():
return a * 10
a = x()


Diez
 
P

Paul Rubin

jena said:
# BEGIN CODE
def test():
def x():
print a
a=2 # ***
a=1
x()
print a

test()
# END CODE

This code fails (on statement print a in def x), if I omit line marked
***, it works (it prints 1\n1\n). It look like when I assign variable
in nested function, I cannot access variable in container function.
I need to assign variable in container function, is any way to do this?

No, this is a big bug in Python, there's no way to specify what scope
you want. The compiler implicitly decides that since you set a to
something inside x(), a must be a local variable. The principle that
explicit is better than implicit was ignored here.

There's a kludgy workaround which is to box the variable:

def test():
def x():
print a[0]
a[0] = 2
a = [1]
print a[0]

However, the arbiters of Python style would prefer that you use a
class instance instead.
 
A

Antoon Pardon

Op 2005-10-09 said:
Hi
I have code

# BEGIN CODE
def test():
def x():
print a
a=2 # ***

a=1
x()
print a

test()
# END CODE

This code fails (on statement print a in def x), if I omit line marked
***, it works (it prints 1\n1\n). It look like when I assign variable in
nested function, I cannot access variable in container function.
I need to assign variable in container function, is any way to do this?

I think the best solution with current python in this situation is to
wrap the nested scope variable in a one element list and use slice
notation to change the variable in a more nested function. Something like the
following:

def test():

def x():
print a[0]
a[:] = [2]

a = [1]
x()
print a[0]

test()

Another solution, IMO more workable if you have more of these variables
is to put them all in a "Scope" object aka Rec, Bunch and probably some
other names and various implementatiosn. (I don't remember from who this
one is. Something like the following:

class Scope(object):
def __init__(__, **kwargs):
for key,value in kwargs.items():
setattr(__, key, value)
__getitem__ = getattr
__setitem__ = setattr

def test():

def x():
print scope.a
scope.a = 2

scope = Scope(a=1)
x()
print scope.a

test()
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top