Scoping Issues

S

SherjilOzair

def adder():
s = 0
def a(x):
s += x
return sum
return a

pos, neg = adder(), adder()
for i in range(10):
print pos(i), neg(-2*i)

This should work, right? Why does it not?

Checkout slide no. 37 of a Tour of Go to know inspiration. Just wanted to see if python was the same as Go in this regard. Sorry, if I'm being rude, or anything.
 
S

Steven D'Aprano

def adder():
s = 0
def a(x):
s += x
return sum
return a

I think you mean "return s", not sum.

This should work, right? Why does it not?

No, it shouldn't. When you have an assignment, such as "s += x", Python
treats s as a local variable. Since s is local to the inner function a(),
it has no initial value, and the += fails.

In Python 3, you can declare s to be a non-local variable with the
nonlocal keyword:

def adder():
s = 0
def a(x):
nonlocal s
s += x
return s
return a


which now works the way you should expect:
8


But in Python 2, which you are using, there is no nonlocal keyword and
you can only write to globals (declaring them with the global keyword) or
locals (with no declaration), not nonlocals.

There are a number of work-arounds to this. One is to use a callable
class:

class Adder:
def __init__(self):
self.s = 0
def __call__(self, x):
self.s += x
return self.s


Another is to use an extra level of indirection, and a mutable argument.
Instead of rebinding the non-local, you simply modify it in place:

def adder():
s = [0]
def a(x):
s[0] += x
return s[0]
return a
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top