Re: Scoping Issues
- From: Steven D'Aprano <steve+comp.lang.python@xxxxxxxxxxxxx>
- Date: 25 May 2012 01:50:15 GMT
On Thu, 24 May 2012 18:23:18 -0700, SherjilOzair wrote:
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:
1add = adder()
add(1)
3add(2)
8add(5)
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
--
Steven
.
- References:
- Scoping Issues
- From: SherjilOzair
- Scoping Issues
- Prev by Date: Re: Dynamic comparison operators
- Next by Date: Re: Namespace hack
- Previous by thread: Scoping Issues
- Next by thread: Is there a custom fields plugin or component of django
- Index(es):
Relevant Pages
|